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.
system.c
00001 /* 00002 system.c - Handles system level commands and real-time processes 00003 Part of Grbl 00004 00005 Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC 00006 00007 Grbl is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 Grbl is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with Grbl. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #include "grbl.h" 00022 00023 00024 void system_init() 00025 { 00026 #ifdef AVRTARGET 00027 CONTROL_DDR &= ~(CONTROL_MASK); // Configure as input pins 00028 #ifdef DISABLE_CONTROL_PIN_PULL_UP 00029 CONTROL_PORT &= ~(CONTROL_MASK); // Normal low operation. Requires external pull-down. 00030 #else 00031 CONTROL_PORT |= CONTROL_MASK; // Enable internal pull-up resistors. Normal high operation. 00032 #endif 00033 CONTROL_PCMSK |= CONTROL_MASK; // Enable specific pins of the Pin Change Interrupt 00034 PCICR |= (1 << CONTROL_INT); // Enable Pin Change Interrupt 00035 #endif 00036 #ifdef STM32F103C8 00037 GPIO_InitTypeDef GPIO_InitStructure; 00038 RCC_APB2PeriphClockCmd(RCC_CONTROL_PORT | RCC_APB2Periph_AFIO, ENABLE); 00039 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 00040 #ifdef DISABLE_CONTROL_PIN_PULL_UP 00041 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 00042 #else 00043 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 00044 #endif 00045 GPIO_InitStructure.GPIO_Pin = CONTROL_MASK; 00046 GPIO_Init(CONTROL_PORT, &GPIO_InitStructure); 00047 00048 GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_RESET_BIT); 00049 GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_FEED_HOLD_BIT); 00050 GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_CYCLE_START_BIT); 00051 GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_SAFETY_DOOR_BIT); 00052 00053 EXTI_InitTypeDef EXTI_InitStructure; 00054 EXTI_InitStructure.EXTI_Line = CONTROL_MASK; // 00055 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //Interrupt mode, optional values for the interrupt EXTI_Mode_Interrupt and event EXTI_Mode_Event. 00056 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //Trigger mode, can be a falling edge trigger EXTI_Trigger_Falling, the rising edge triggered EXTI_Trigger_Rising, or any level (rising edge and falling edge trigger EXTI_Trigger_Rising_Falling) 00057 EXTI_InitStructure.EXTI_LineCmd = ENABLE; 00058 EXTI_Init(&EXTI_InitStructure); 00059 00060 NVIC_InitTypeDef NVIC_InitStructure; 00061 NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //Enable keypad external interrupt channel 00062 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //Priority 2, 00063 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //Sub priority 2 00064 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Enable external interrupt channel 00065 NVIC_Init(&NVIC_InitStructure); 00066 #endif 00067 } 00068 00069 00070 // Returns control pin state as a uint8 bitfield. Each bit indicates the input pin state, where 00071 // triggered is 1 and not triggered is 0. Invert mask is applied. Bitfield organization is 00072 // defined by the CONTROL_PIN_INDEX in the header file. 00073 uint8_t system_control_get_state() 00074 { 00075 uint8_t control_state = 0; 00076 #ifdef AVRTARGET 00077 uint8_t pin = (CONTROL_PIN & CONTROL_MASK); 00078 #endif 00079 #ifdef WIN32 00080 uint8_t pin = 0; 00081 #endif 00082 #ifdef STM32F103C8 00083 uint16_t pin= GPIO_ReadInputData(CONTROL_PIN_PORT); 00084 #endif 00085 #ifdef INVERT_CONTROL_PIN_MASK 00086 pin ^= INVERT_CONTROL_PIN_MASK; 00087 #endif 00088 if (pin) { 00089 #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN 00090 if (bit_isfalse(pin,(1<<CONTROL_SAFETY_DOOR_BIT))) { control_state |= CONTROL_PIN_INDEX_SAFETY_DOOR; } 00091 #endif 00092 if (bit_isfalse(pin,(1<<CONTROL_RESET_BIT))) { control_state |= CONTROL_PIN_INDEX_RESET; } 00093 if (bit_isfalse(pin,(1<<CONTROL_FEED_HOLD_BIT))) { control_state |= CONTROL_PIN_INDEX_FEED_HOLD; } 00094 if (bit_isfalse(pin,(1<<CONTROL_CYCLE_START_BIT))) { control_state |= CONTROL_PIN_INDEX_CYCLE_START; } 00095 } 00096 return(control_state); 00097 } 00098 00099 00100 // Pin change interrupt for pin-out commands, i.e. cycle start, feed hold, and reset. Sets 00101 // only the realtime command execute variable to have the main program execute these when 00102 // its ready. This works exactly like the character-based realtime commands when picked off 00103 // directly from the incoming serial data stream. 00104 #ifdef AVRTARGET 00105 ISR(CONTROL_INT_vect) 00106 { 00107 uint8_t pin = system_control_get_state(); 00108 if (pin) { 00109 if (bit_istrue(pin,CONTROL_PIN_INDEX_RESET)) { 00110 mc_reset(); 00111 } else if (bit_istrue(pin,CONTROL_PIN_INDEX_CYCLE_START)) { 00112 bit_true(sys_rt_exec_state, EXEC_CYCLE_START); 00113 #ifndef ENABLE_SAFETY_DOOR_INPUT_PIN 00114 } else if (bit_istrue(pin,CONTROL_PIN_INDEX_FEED_HOLD)) { 00115 bit_true(sys_rt_exec_state, EXEC_FEED_HOLD); 00116 #else 00117 } else if (bit_istrue(pin,CONTROL_PIN_INDEX_SAFETY_DOOR)) { 00118 bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR); 00119 #endif 00120 } 00121 } 00122 } 00123 #endif 00124 #if defined (STM32F103C8) 00125 void EXTI9_5_IRQHandler(void) 00126 { 00127 EXTI_ClearITPendingBit((1 << CONTROL_RESET_BIT) | (1 << CONTROL_FEED_HOLD_BIT) | (1 << CONTROL_CYCLE_START_BIT) | (1 << CONTROL_SAFETY_DOOR_BIT)); 00128 uint8_t pin = system_control_get_state(); 00129 if (pin) 00130 { 00131 if (bit_istrue(pin,CONTROL_PIN_INDEX_RESET)) 00132 { 00133 mc_reset(); 00134 } 00135 else if (bit_istrue(pin, CONTROL_PIN_INDEX_CYCLE_START)) 00136 { 00137 bit_true(sys_rt_exec_state, EXEC_CYCLE_START); 00138 } 00139 #ifndef ENABLE_SAFETY_DOOR_INPUT_PIN 00140 else if (bit_istrue(pin, CONTROL_PIN_INDEX_FEED_HOLD)) 00141 { 00142 bit_true(sys_rt_exec_state, EXEC_FEED_HOLD); 00143 } 00144 #else 00145 else if (bit_istrue(pin, CONTROL_PIN_INDEX_SAFETY_DOOR)) 00146 { 00147 bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR); 00148 } 00149 #endif 00150 NVIC_ClearPendingIRQ(EXTI9_5_IRQn); 00151 } 00152 } 00153 #endif 00154 00155 // Returns if safety door is ajar(T) or closed(F), based on pin state. 00156 uint8_t system_check_safety_door_ajar() 00157 { 00158 #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN 00159 return(system_control_get_state() & CONTROL_PIN_INDEX_SAFETY_DOOR); 00160 #else 00161 return(false); // Input pin not enabled, so just return that it's closed. 00162 #endif 00163 } 00164 00165 00166 // Executes user startup script, if stored. 00167 void system_execute_startup(char *line) 00168 { 00169 uint8_t n; 00170 for (n=0; n < N_STARTUP_LINE; n++) { 00171 if (!(settings_read_startup_line(n, line))) { 00172 line[0] = 0; 00173 report_execute_startup_message(line,STATUS_SETTING_READ_FAIL); 00174 } else { 00175 if (line[0] != 0) { 00176 uint8_t status_code = gc_execute_line(line); 00177 report_execute_startup_message(line,status_code); 00178 } 00179 } 00180 } 00181 } 00182 00183 00184 // Directs and executes one line of formatted input from protocol_process. While mostly 00185 // incoming streaming g-code blocks, this also executes Grbl internal commands, such as 00186 // settings, initiating the homing cycle, and toggling switch states. This differs from 00187 // the realtime command module by being susceptible to when Grbl is ready to execute the 00188 // next line during a cycle, so for switches like block delete, the switch only effects 00189 // the lines that are processed afterward, not necessarily real-time during a cycle, 00190 // since there are motions already stored in the buffer. However, this 'lag' should not 00191 // be an issue, since these commands are not typically used during a cycle. 00192 uint8_t system_execute_line(char *line) 00193 { 00194 uint8_t char_counter = 1; 00195 uint8_t helper_var = 0; // Helper variable 00196 float parameter, value; 00197 switch( line[char_counter] ) { 00198 case 0 : report_grbl_help(); break; 00199 case 'J' : // Jogging 00200 // Execute only if in IDLE or JOG states. 00201 if (sys.state != STATE_IDLE && sys.state != STATE_JOG) { return(STATUS_IDLE_ERROR); } 00202 if(line[2] != '=') { return(STATUS_INVALID_STATEMENT); } 00203 return(gc_execute_line(line)); // NOTE: $J= is ignored inside g-code parser and used to detect jog motions. 00204 break; 00205 case '$': case 'G': case 'C': case 'X': 00206 if ( line[2] != 0 ) { return(STATUS_INVALID_STATEMENT); } 00207 switch( line[1] ) { 00208 case '$' : // Prints Grbl settings 00209 if ( sys.state & (STATE_CYCLE | STATE_HOLD) ) { return(STATUS_IDLE_ERROR); } // Block during cycle. Takes too long to print. 00210 else { report_grbl_settings(); } 00211 break; 00212 case 'G' : // Prints gcode parser state 00213 // TODO: Move this to realtime commands for GUIs to request this data during suspend-state. 00214 report_gcode_modes(); 00215 break; 00216 case 'C' : // Set check g-code mode [IDLE/CHECK] 00217 // Perform reset when toggling off. Check g-code mode should only work if Grbl 00218 // is idle and ready, regardless of alarm locks. This is mainly to keep things 00219 // simple and consistent. 00220 if ( sys.state == STATE_CHECK_MODE ) { 00221 mc_reset(); 00222 report_feedback_message(MESSAGE_DISABLED); 00223 } else { 00224 if (sys.state) { return(STATUS_IDLE_ERROR); } // Requires no alarm mode. 00225 sys.state = STATE_CHECK_MODE; 00226 report_feedback_message(MESSAGE_ENABLED); 00227 } 00228 break; 00229 case 'X' : // Disable alarm lock [ALARM] 00230 if (sys.state == STATE_ALARM) { 00231 // Block if safety door is ajar. 00232 if (system_check_safety_door_ajar()) { return(STATUS_CHECK_DOOR); } 00233 report_feedback_message(MESSAGE_ALARM_UNLOCK); 00234 sys.state = STATE_IDLE; 00235 // Don't run startup script. Prevents stored moves in startup from causing accidents. 00236 } // Otherwise, no effect. 00237 break; 00238 } 00239 break; 00240 default : 00241 // Block any system command that requires the state as IDLE/ALARM. (i.e. EEPROM, homing) 00242 if ( !(sys.state == STATE_IDLE || sys.state == STATE_ALARM) ) { return(STATUS_IDLE_ERROR); } 00243 switch( line[1] ) { 00244 case '#' : // Print Grbl NGC parameters 00245 if ( line[2] != 0 ) { return(STATUS_INVALID_STATEMENT); } 00246 else { report_ngc_parameters(); } 00247 break; 00248 case 'H' : // Perform homing cycle [IDLE/ALARM] 00249 if (bit_isfalse(settings.flags,BITFLAG_HOMING_ENABLE)) {return(STATUS_SETTING_DISABLED); } 00250 if (system_check_safety_door_ajar()) { return(STATUS_CHECK_DOOR); } // Block if safety door is ajar. 00251 sys.state = STATE_HOMING; // Set system state variable 00252 if (line[2] == 0) { 00253 mc_homing_cycle(HOMING_CYCLE_ALL); 00254 #ifdef HOMING_SINGLE_AXIS_COMMANDS 00255 } else if (line[3] == 0) { 00256 switch (line[2]) { 00257 case 'X': mc_homing_cycle(HOMING_CYCLE_X); break; 00258 case 'Y': mc_homing_cycle(HOMING_CYCLE_Y); break; 00259 case 'Z': mc_homing_cycle(HOMING_CYCLE_Z); break; 00260 default: return(STATUS_INVALID_STATEMENT); 00261 } 00262 #endif 00263 } else { return(STATUS_INVALID_STATEMENT); } 00264 if (!sys.abort) { // Execute startup scripts after successful homing. 00265 sys.state = STATE_IDLE; // Set to IDLE when complete. 00266 st_go_idle(); // Set steppers to the settings idle state before returning. 00267 if (line[2] == 0) { system_execute_startup(line); } 00268 } 00269 break; 00270 case 'S' : // Puts Grbl to sleep [IDLE/ALARM] 00271 if ((line[2] != 'L') || (line[3] != 'P') || (line[4] != 0)) { return(STATUS_INVALID_STATEMENT); } 00272 system_set_exec_state_flag(EXEC_SLEEP); // Set to execute sleep mode immediately 00273 break; 00274 case 'I' : // Print or store build info. [IDLE/ALARM] 00275 if ( line[++char_counter] == 0 ) { 00276 settings_read_build_info(line); 00277 report_build_info(line); 00278 #ifdef ENABLE_BUILD_INFO_WRITE_COMMAND 00279 } else { // Store startup line [IDLE/ALARM] 00280 if(line[char_counter++] != '=') { return(STATUS_INVALID_STATEMENT); } 00281 helper_var = char_counter; // Set helper variable as counter to start of user info line. 00282 do { 00283 line[char_counter-helper_var] = line[char_counter]; 00284 } while (line[char_counter++] != 0); 00285 settings_store_build_info(line); 00286 #endif 00287 } 00288 break; 00289 case 'R' : // Restore defaults [IDLE/ALARM] 00290 if ((line[2] != 'S') || (line[3] != 'T') || (line[4] != '=') || (line[6] != 0)) { return(STATUS_INVALID_STATEMENT); } 00291 switch (line[5]) { 00292 #ifdef ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS 00293 case '$': settings_restore(SETTINGS_RESTORE_DEFAULTS); break; 00294 #endif 00295 #ifdef ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS 00296 case '#': settings_restore(SETTINGS_RESTORE_PARAMETERS); break; 00297 #endif 00298 #ifdef ENABLE_RESTORE_EEPROM_WIPE_ALL 00299 case '*': settings_restore(SETTINGS_RESTORE_ALL); break; 00300 #endif 00301 default: return(STATUS_INVALID_STATEMENT); 00302 } 00303 report_feedback_message(MESSAGE_RESTORE_DEFAULTS); 00304 mc_reset(); // Force reset to ensure settings are initialized correctly. 00305 break; 00306 case 'N' : // Startup lines. [IDLE/ALARM] 00307 if ( line[++char_counter] == 0 ) { // Print startup lines 00308 for (helper_var=0; helper_var < N_STARTUP_LINE; helper_var++) { 00309 if (!(settings_read_startup_line(helper_var, line))) { 00310 report_status_message(STATUS_SETTING_READ_FAIL); 00311 } else { 00312 report_startup_line(helper_var,line); 00313 } 00314 } 00315 break; 00316 } else { // Store startup line [IDLE Only] Prevents motion during ALARM. 00317 if (sys.state != STATE_IDLE) { return(STATUS_IDLE_ERROR); } // Store only when idle. 00318 helper_var = true; // Set helper_var to flag storing method. 00319 // No break. Continues into default: to read remaining command characters. 00320 } 00321 default : // Storing setting methods [IDLE/ALARM] 00322 if(!read_float(line, &char_counter, ¶meter)) { return(STATUS_BAD_NUMBER_FORMAT); } 00323 if(line[char_counter++] != '=') { return(STATUS_INVALID_STATEMENT); } 00324 if (helper_var) { // Store startup line 00325 // Prepare sending gcode block to gcode parser by shifting all characters 00326 helper_var = char_counter; // Set helper variable as counter to start of gcode block 00327 do { 00328 line[char_counter-helper_var] = line[char_counter]; 00329 } while (line[char_counter++] != 0); 00330 // Execute gcode block to ensure block is valid. 00331 helper_var = gc_execute_line(line); // Set helper_var to returned status code. 00332 if (helper_var) { return(helper_var); } 00333 else { 00334 helper_var = truncf(parameter); // Set helper_var to int value of parameter 00335 settings_store_startup_line(helper_var,line); 00336 } 00337 } else { // Store global setting. 00338 if(!read_float(line, &char_counter, &value)) { return(STATUS_BAD_NUMBER_FORMAT); } 00339 if((line[char_counter] != 0) || (parameter > 255)) { return(STATUS_INVALID_STATEMENT); } 00340 return(settings_store_global_setting((uint8_t)parameter, value)); 00341 } 00342 } 00343 } 00344 return(STATUS_OK); // If '$' command makes it to here, then everything's ok. 00345 } 00346 00347 00348 00349 void system_flag_wco_change() 00350 { 00351 #ifdef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE 00352 protocol_buffer_synchronize(); 00353 #endif 00354 sys.report_wco_counter = 0; 00355 } 00356 00357 00358 // Returns machine position of axis 'idx'. Must be sent a 'step' array. 00359 // NOTE: If motor steps and machine position are not in the same coordinate frame, this function 00360 // serves as a central place to compute the transformation. 00361 float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx) 00362 { 00363 float pos; 00364 #ifdef COREXY 00365 if (idx==X_AXIS) { 00366 pos = (float)system_convert_corexy_to_x_axis_steps(steps) / settings.steps_per_mm[idx]; 00367 } else if (idx==Y_AXIS) { 00368 pos = (float)system_convert_corexy_to_y_axis_steps(steps) / settings.steps_per_mm[idx]; 00369 } else { 00370 pos = steps[idx]/settings.steps_per_mm[idx]; 00371 } 00372 #else 00373 pos = steps[idx]/settings.steps_per_mm[idx]; 00374 #endif 00375 return(pos); 00376 } 00377 00378 00379 void system_convert_array_steps_to_mpos(float *position, int32_t *steps) 00380 { 00381 uint8_t idx; 00382 for (idx=0; idx<N_AXIS; idx++) { 00383 position[idx] = system_convert_axis_steps_to_mpos(steps, idx); 00384 } 00385 return; 00386 } 00387 00388 00389 // CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps. 00390 #ifdef COREXY 00391 int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps) 00392 { 00393 return( (steps[A_MOTOR] + steps[B_MOTOR])/2 ); 00394 } 00395 int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps) 00396 { 00397 return( (steps[A_MOTOR] - steps[B_MOTOR])/2 ); 00398 } 00399 #endif 00400 00401 00402 // Checks and reports if target array exceeds machine travel limits. 00403 uint8_t system_check_travel_limits(float *target) 00404 { 00405 uint8_t idx; 00406 for (idx=0; idx<N_AXIS; idx++) { 00407 #ifdef HOMING_FORCE_SET_ORIGIN 00408 // When homing forced set origin is enabled, soft limits checks need to account for directionality. 00409 // NOTE: max_travel is stored as negative 00410 if (bit_istrue(settings.homing_dir_mask,bit(idx))) { 00411 if (target[idx] < 0 || target[idx] > -settings.max_travel[idx]) { return(true); } 00412 } else { 00413 if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); } 00414 } 00415 #else 00416 // NOTE: max_travel is stored as negative 00417 if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); } 00418 #endif 00419 } 00420 return(false); 00421 } 00422 00423 #ifdef WIN32 00424 extern CRITICAL_SECTION CriticalSection; 00425 #endif 00426 00427 // Special handlers for setting and clearing Grbl's real-time execution flags. 00428 void system_set_exec_state_flag(uint8_t mask) { 00429 #ifdef AVRTARGET 00430 uint8_t sreg = SREG; 00431 cli(); 00432 sys_rt_exec_state |= (mask); 00433 SREG = sreg; 00434 #endif 00435 #ifdef WIN32 00436 EnterCriticalSection(&CriticalSection); 00437 sys_rt_exec_state |= (mask); 00438 LeaveCriticalSection(&CriticalSection); 00439 #endif 00440 #ifdef STM32F103C8 00441 __disable_irq(); 00442 sys_rt_exec_state |= (mask); 00443 __enable_irq(); 00444 #endif 00445 } 00446 00447 void system_clear_exec_state_flag(uint8_t mask) { 00448 #ifdef AVRTARGET 00449 uint8_t sreg = SREG; 00450 cli(); 00451 sys_rt_exec_state &= ~(mask); 00452 SREG = sreg; 00453 #endif 00454 #ifdef WIN32 00455 EnterCriticalSection(&CriticalSection); 00456 sys_rt_exec_state &= ~(mask); 00457 LeaveCriticalSection(&CriticalSection); 00458 #endif 00459 #ifdef STM32F103C8 00460 __disable_irq(); 00461 sys_rt_exec_state &= ~(mask); 00462 __enable_irq(); 00463 #endif 00464 } 00465 00466 void system_set_exec_alarm(uint8_t code) { 00467 #ifdef AVRTARGET 00468 uint8_t sreg = SREG; 00469 cli(); 00470 sys_rt_exec_alarm = code; 00471 SREG = sreg; 00472 #endif 00473 #ifdef WIN32 00474 EnterCriticalSection(&CriticalSection); 00475 sys_rt_exec_alarm |= (code); 00476 LeaveCriticalSection(&CriticalSection); 00477 #endif 00478 #ifdef STM32F103C8 00479 __disable_irq(); 00480 sys_rt_exec_alarm |= (code); 00481 __enable_irq(); 00482 #endif 00483 } 00484 00485 void system_clear_exec_alarm() { 00486 #ifdef AVRTARGET 00487 uint8_t sreg = SREG; 00488 cli(); 00489 sys_rt_exec_alarm = 0; 00490 SREG = sreg; 00491 #endif 00492 #ifdef WIN32 00493 EnterCriticalSection(&CriticalSection); 00494 sys_rt_exec_alarm = 0; 00495 LeaveCriticalSection(&CriticalSection); 00496 #endif 00497 #ifdef STM32F103C8 00498 __disable_irq(); 00499 sys_rt_exec_alarm = 0; 00500 __enable_irq(); 00501 #endif 00502 } 00503 00504 void system_set_exec_motion_override_flag(uint8_t mask) { 00505 #ifdef AVRTARGET 00506 uint8_t sreg = SREG; 00507 cli(); 00508 sys_rt_exec_motion_override |= (mask); 00509 SREG = sreg; 00510 #endif 00511 #ifdef WIN32 00512 EnterCriticalSection(&CriticalSection); 00513 sys_rt_exec_motion_override |= (mask); 00514 LeaveCriticalSection(&CriticalSection); 00515 #endif 00516 #ifdef STM32F103C8 00517 __disable_irq(); 00518 sys_rt_exec_motion_override |= (mask); 00519 __enable_irq(); 00520 #endif 00521 } 00522 00523 void system_set_exec_accessory_override_flag(uint8_t mask) { 00524 #ifdef AVRTARGET 00525 uint8_t sreg = SREG; 00526 cli(); 00527 sys_rt_exec_accessory_override |= (mask); 00528 SREG = sreg; 00529 #endif 00530 #ifdef WIN32 00531 EnterCriticalSection(&CriticalSection); 00532 sys_rt_exec_accessory_override |= (mask); 00533 LeaveCriticalSection(&CriticalSection); 00534 #endif 00535 #ifdef STM32F103C8 00536 __disable_irq(); 00537 sys_rt_exec_accessory_override |= (mask); 00538 __enable_irq(); 00539 #endif 00540 } 00541 00542 void system_clear_exec_motion_overrides() { 00543 #ifdef AVRTARGET 00544 uint8_t sreg = SREG; 00545 cli(); 00546 sys_rt_exec_motion_override = 0; 00547 SREG = sreg; 00548 #endif 00549 #ifdef WIN32 00550 EnterCriticalSection(&CriticalSection); 00551 sys_rt_exec_motion_override = 0; 00552 LeaveCriticalSection(&CriticalSection); 00553 #endif 00554 #ifdef STM32F103C8 00555 __disable_irq(); 00556 sys_rt_exec_motion_override = 0; 00557 __enable_irq(); 00558 #endif 00559 } 00560 00561 void system_clear_exec_accessory_overrides() { 00562 #ifdef AVRTARGET 00563 uint8_t sreg = SREG; 00564 cli(); 00565 sys_rt_exec_accessory_override = 0; 00566 SREG = sreg; 00567 #endif 00568 #ifdef WIN32 00569 EnterCriticalSection(&CriticalSection); 00570 sys_rt_exec_accessory_override = 0; 00571 LeaveCriticalSection(&CriticalSection); 00572 #endif 00573 #ifdef STM32F103C8 00574 __disable_irq(); 00575 sys_rt_exec_accessory_override = 0; 00576 __enable_irq(); 00577 #endif 00578 }
Generated on Tue Jul 12 2022 20:45:32 by
 1.7.2
 1.7.2