Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
settings.c
00001 /* 00002 settings.c - eeprom configuration handling 00003 Part of Grbl 00004 00005 Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC 00006 Copyright (c) 2009-2011 Simen Svale Skogsrud 00007 00008 Grbl is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation, either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 Grbl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with Grbl. If not, see <http://www.gnu.org/licenses/>. 00020 */ 00021 00022 #include "grbl.h" 00023 00024 settings_t settings; 00025 00026 00027 // Method to store startup lines into EEPROM 00028 void settings_store_startup_line(uint8_t n, char *line) 00029 { 00030 #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE 00031 protocol_buffer_synchronize(); // A startup line may contain a motion and be executing. 00032 #endif 00033 uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK; 00034 memcpy_to_eeprom_with_checksum(addr,(char*)line, LINE_BUFFER_SIZE); 00035 } 00036 00037 00038 // Method to store build info into EEPROM 00039 // NOTE: This function can only be called in IDLE state. 00040 void settings_store_build_info(char *line) 00041 { 00042 // Build info can only be stored when state is IDLE. 00043 memcpy_to_eeprom_with_checksum(EEPROM_ADDR_BUILD_INFO,(char*)line, LINE_BUFFER_SIZE); 00044 } 00045 00046 00047 // Method to store coord data parameters into EEPROM 00048 void settings_write_coord_data(uint8_t coord_select, float *coord_data) 00049 { 00050 #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE 00051 protocol_buffer_synchronize(); 00052 #endif 00053 uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS; 00054 memcpy_to_eeprom_with_checksum(addr,(char*)coord_data, sizeof(float)*N_AXIS); 00055 } 00056 00057 00058 // Method to store Grbl global settings struct and version number into EEPROM 00059 // NOTE: This function can only be called in IDLE state. 00060 void write_global_settings() 00061 { 00062 eeprom_put_char(0, SETTINGS_VERSION); 00063 memcpy_to_eeprom_with_checksum(EEPROM_ADDR_GLOBAL, (char*)&settings, sizeof(settings_t)); 00064 } 00065 00066 00067 // Method to restore EEPROM-saved Grbl global settings back to defaults. 00068 void settings_restore(uint8_t restore_flag) { 00069 if (restore_flag & SETTINGS_RESTORE_DEFAULTS) { 00070 settings.pulse_microseconds = DEFAULT_STEP_PULSE_MICROSECONDS; 00071 settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME; 00072 settings.step_invert_mask = DEFAULT_STEPPING_INVERT_MASK; 00073 settings.dir_invert_mask = DEFAULT_DIRECTION_INVERT_MASK; 00074 settings.status_report_mask = DEFAULT_STATUS_REPORT_MASK; 00075 settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION; 00076 settings.arc_tolerance = DEFAULT_ARC_TOLERANCE; 00077 00078 settings.rpm_max = DEFAULT_SPINDLE_RPM_MAX; 00079 settings.rpm_min = DEFAULT_SPINDLE_RPM_MIN; 00080 00081 settings.homing_dir_mask = DEFAULT_HOMING_DIR_MASK; 00082 settings.homing_feed_rate = DEFAULT_HOMING_FEED_RATE; 00083 settings.homing_seek_rate = DEFAULT_HOMING_SEEK_RATE; 00084 settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY; 00085 settings.homing_pulloff = DEFAULT_HOMING_PULLOFF; 00086 00087 settings.flags = 0; 00088 if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; } 00089 if (DEFAULT_LASER_MODE) { settings.flags |= BITFLAG_LASER_MODE; } 00090 if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; } 00091 if (DEFAULT_HARD_LIMIT_ENABLE) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; } 00092 if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; } 00093 if (DEFAULT_SOFT_LIMIT_ENABLE) { settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; } 00094 if (DEFAULT_INVERT_LIMIT_PINS) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; } 00095 if (DEFAULT_INVERT_PROBE_PIN) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; } 00096 00097 settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM; 00098 settings.steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM; 00099 settings.steps_per_mm[Z_AXIS] = DEFAULT_Z_STEPS_PER_MM; 00100 settings.max_rate[X_AXIS] = DEFAULT_X_MAX_RATE; 00101 settings.max_rate[Y_AXIS] = DEFAULT_Y_MAX_RATE; 00102 settings.max_rate[Z_AXIS] = DEFAULT_Z_MAX_RATE; 00103 settings.acceleration[X_AXIS] = DEFAULT_X_ACCELERATION; 00104 settings.acceleration[Y_AXIS] = DEFAULT_Y_ACCELERATION; 00105 settings.acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION; 00106 settings.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL); 00107 settings.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL); 00108 settings.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL); 00109 00110 write_global_settings(); 00111 } 00112 00113 if (restore_flag & SETTINGS_RESTORE_PARAMETERS) { 00114 uint8_t idx; 00115 float coord_data[N_AXIS]; 00116 memset(&coord_data, 0, sizeof(coord_data)); 00117 for (idx=0; idx <= SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); } 00118 } 00119 00120 if (restore_flag & SETTINGS_RESTORE_STARTUP_LINES) { 00121 #if N_STARTUP_LINE > 0 00122 eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK, 0); 00123 eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+1, 0); // Checksum 00124 #endif 00125 #if N_STARTUP_LINE > 1 00126 eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+1), 0); 00127 eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+2), 0); // Checksum 00128 #endif 00129 } 00130 00131 if (restore_flag & SETTINGS_RESTORE_BUILD_INFO) { 00132 eeprom_put_char(EEPROM_ADDR_BUILD_INFO , 0); 00133 eeprom_put_char(EEPROM_ADDR_BUILD_INFO+1 , 0); // Checksum 00134 } 00135 } 00136 00137 00138 // Reads startup line from EEPROM. Updated pointed line string data. 00139 uint8_t settings_read_startup_line(uint8_t n, char *line) 00140 { 00141 uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK; 00142 if (!(memcpy_from_eeprom_with_checksum((char*)line, addr, LINE_BUFFER_SIZE))) { 00143 // Reset line with default value 00144 line[0] = 0; // Empty line 00145 settings_store_startup_line(n, line); 00146 return(false); 00147 } 00148 return(true); 00149 } 00150 00151 00152 // Reads startup line from EEPROM. Updated pointed line string data. 00153 uint8_t settings_read_build_info(char *line) 00154 { 00155 if (!(memcpy_from_eeprom_with_checksum((char*)line, EEPROM_ADDR_BUILD_INFO, LINE_BUFFER_SIZE))) { 00156 // Reset line with default value 00157 line[0] = 0; // Empty line 00158 settings_store_build_info(line); 00159 return(false); 00160 } 00161 return(true); 00162 } 00163 00164 00165 // Read selected coordinate data from EEPROM. Updates pointed coord_data value. 00166 uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data) 00167 { 00168 uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS; 00169 if (!(memcpy_from_eeprom_with_checksum((char*)coord_data, addr, sizeof(float)*N_AXIS))) { 00170 // Reset with default zero vector 00171 clear_vector_float(coord_data); 00172 settings_write_coord_data(coord_select,coord_data); 00173 return(false); 00174 } 00175 return(true); 00176 } 00177 00178 00179 // Reads Grbl global settings struct from EEPROM. 00180 uint8_t read_global_settings() { 00181 // Check version-byte of eeprom 00182 uint8_t version = eeprom_get_char(0); 00183 if (version == SETTINGS_VERSION) { 00184 // Read settings-record and check checksum 00185 if (!(memcpy_from_eeprom_with_checksum((char*)&settings, EEPROM_ADDR_GLOBAL, sizeof(settings_t)))) { 00186 return(false); 00187 } 00188 } else { 00189 return(false); 00190 } 00191 return(true); 00192 } 00193 00194 00195 // A helper method to set settings from command line 00196 uint8_t settings_store_global_setting(uint8_t parameter, float value) { 00197 if (value < 0.0f) { return(STATUS_NEGATIVE_VALUE); } 00198 if (parameter >= AXIS_SETTINGS_START_VAL) { 00199 // Store axis configuration. Axis numbering sequence set by AXIS_SETTING defines. 00200 // NOTE: Ensure the setting index corresponds to the report.c settings printout. 00201 parameter -= AXIS_SETTINGS_START_VAL; 00202 uint8_t set_idx = 0; 00203 while (set_idx < AXIS_N_SETTINGS) { 00204 if (parameter < N_AXIS) { 00205 // Valid axis setting found. 00206 switch (set_idx) { 00207 case 0: 00208 #ifdef MAX_STEP_RATE_HZ 00209 if (value*settings.max_rate[parameter] >(MAX_STEP_RATE_HZ*60.0f)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } 00210 #endif 00211 settings.steps_per_mm[parameter] = value; 00212 break; 00213 case 1: 00214 #ifdef MAX_STEP_RATE_HZ 00215 if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0f)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } 00216 #endif 00217 settings.max_rate[parameter] = value; 00218 break; 00219 case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. 00220 case 3: settings.max_travel[parameter] = -value; break; // Store as negative for grbl internal use. 00221 } 00222 break; // Exit while-loop after setting has been configured and proceed to the EEPROM write call. 00223 } else { 00224 set_idx++; 00225 // If axis index greater than N_AXIS or setting index greater than number of axis settings, error out. 00226 if ((parameter < AXIS_SETTINGS_INCREMENT) || (set_idx == AXIS_N_SETTINGS)) { return(STATUS_INVALID_STATEMENT); } 00227 parameter -= AXIS_SETTINGS_INCREMENT; 00228 } 00229 } 00230 } else { 00231 // Store non-axis Grbl settings 00232 uint8_t int_value = truncf(value); 00233 switch(parameter) { 00234 case 0: 00235 if (int_value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); } 00236 settings.pulse_microseconds = int_value; break; 00237 case 1: settings.stepper_idle_lock_time = int_value; break; 00238 case 2: 00239 settings.step_invert_mask = int_value; 00240 st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks. 00241 break; 00242 case 3: 00243 settings.dir_invert_mask = int_value; 00244 st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks. 00245 break; 00246 case 4: // Reset to ensure change. Immediate re-init may cause problems. 00247 if (int_value) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; } 00248 else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; } 00249 break; 00250 case 5: // Reset to ensure change. Immediate re-init may cause problems. 00251 if (int_value) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; } 00252 else { settings.flags &= ~BITFLAG_INVERT_LIMIT_PINS; } 00253 break; 00254 case 6: // Reset to ensure change. Immediate re-init may cause problems. 00255 if (int_value) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; } 00256 else { settings.flags &= ~BITFLAG_INVERT_PROBE_PIN; } 00257 probe_configure_invert_mask(false); 00258 break; 00259 case 10: settings.status_report_mask = int_value; break; 00260 case 11: settings.junction_deviation = value; break; 00261 case 12: settings.arc_tolerance = value; break; 00262 case 13: 00263 if (int_value) { settings.flags |= BITFLAG_REPORT_INCHES; } 00264 else { settings.flags &= ~BITFLAG_REPORT_INCHES; } 00265 system_flag_wco_change(); // Make sure WCO is immediately updated. 00266 break; 00267 case 20: 00268 if (int_value) { 00269 if (bit_isfalse(settings.flags, BITFLAG_HOMING_ENABLE)) { return(STATUS_SOFT_LIMIT_ERROR); } 00270 settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; 00271 } else { settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; } 00272 break; 00273 case 21: 00274 if (int_value) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; } 00275 else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; } 00276 limits_init(); // Re-init to immediately change. NOTE: Nice to have but could be problematic later. 00277 break; 00278 case 22: 00279 if (int_value) { settings.flags |= BITFLAG_HOMING_ENABLE; } 00280 else { 00281 settings.flags &= ~BITFLAG_HOMING_ENABLE; 00282 settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; // Force disable soft-limits. 00283 } 00284 break; 00285 case 23: settings.homing_dir_mask = int_value; break; 00286 case 24: settings.homing_feed_rate = value; break; 00287 case 25: settings.homing_seek_rate = value; break; 00288 case 26: settings.homing_debounce_delay = int_value; break; 00289 case 27: settings.homing_pulloff = value; break; 00290 case 30: settings.rpm_max = value; spindle_init(); break; // Re-initialize spindle rpm calibration 00291 case 31: settings.rpm_min = value; spindle_init(); break; // Re-initialize spindle rpm calibration 00292 case 32: 00293 #ifdef VARIABLE_SPINDLE 00294 if (int_value) { settings.flags |= BITFLAG_LASER_MODE; } 00295 else { settings.flags &= ~BITFLAG_LASER_MODE; } 00296 #else 00297 return(STATUS_SETTING_DISABLED_LASER); 00298 #endif 00299 break; 00300 default: 00301 return(STATUS_INVALID_STATEMENT); 00302 } 00303 } 00304 write_global_settings(); 00305 return(STATUS_OK); 00306 } 00307 00308 00309 // Initialize the config subsystem 00310 void settings_init() { 00311 if(!read_global_settings()) { 00312 report_status_message(STATUS_SETTING_READ_FAIL); 00313 settings_restore(SETTINGS_RESTORE_ALL); // Force restore all EEPROM data. 00314 report_grbl_settings(); 00315 } 00316 } 00317
Generated on Tue Jul 12 2022 16:02:26 by
1.7.2