gnea\grbl-Mega  1.0f
Source Code Documentation ( Internal Workings )
spindle_control.c
Go to the documentation of this file.
1 /*
2  spindle_control.c - spindle control methods
3  Part of Grbl
4 
5  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
6  Copyright (c) 2009-2011 Simen Svale Skogsrud
7 
8  Grbl is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  Grbl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with Grbl. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #include "grbl.h"
23 
24 
25 static float pwm_gradient;
26 
27 
29 {
30 // Configure variable spindle PWM and enable pin, if required.
31  SPINDLE_PWM_DDR |= (1<<SPINDLE_PWM_BIT);
32  SPINDLE_TCCRA_REGISTER = SPINDLE_TCCRA_INIT_MASK;
33  SPINDLE_TCCRB_REGISTER = SPINDLE_TCCRB_INIT_MASK;
34  SPINDLE_OCRA_REGISTER = SPINDLE_OCRA_TOP_VALUE;
35  SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT);
36  SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT);
37 
38  pwm_gradient = SPINDLE_PWM_RANGE/(settings.rpm_max-settings.rpm_min);
39  spindle_stop();
40 }
41 
42 
44 {
45  #ifdef INVERT_SPINDLE_ENABLE_PIN
46  if (bit_isfalse(SPINDLE_ENABLE_PORT,(1<<SPINDLE_ENABLE_BIT)) && (SPINDLE_TCCRA_REGISTER & (1<<SPINDLE_COMB_BIT))) {
47  #else
48  if (bit_istrue(SPINDLE_ENABLE_PORT,(1<<SPINDLE_ENABLE_BIT)) && (SPINDLE_TCCRA_REGISTER & (1<<SPINDLE_COMB_BIT))) {
49  #endif
50  if (SPINDLE_DIRECTION_PORT & (1<<SPINDLE_DIRECTION_BIT)) { return(SPINDLE_STATE_CCW); }
51  else { return(SPINDLE_STATE_CW); }
52  }
53  return(SPINDLE_STATE_DISABLE);
54 }
55 
57 // Called by various main program and ISR routines. Keep routine small, fast, and efficient.
58 // Called by spindle_init(), spindle_set_speed(), spindle_set_state(), and mc_reset().
60 {
61  SPINDLE_TCCRA_REGISTER &= ~(1<<SPINDLE_COMB_BIT);
62  #ifdef INVERT_SPINDLE_ENABLE_PIN
63  SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
64  #else
65  SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
66  #endif
67 }
68 
70 // and stepper ISR. Keep routine small and efficient.
71 void spindle_set_speed(uint16_t pwm_value)
72 {
73  SPINDLE_OCR_REGISTER = pwm_value;
74  if (pwm_value == SPINDLE_PWM_OFF_VALUE) {
75  SPINDLE_TCCRA_REGISTER &= ~(1<<SPINDLE_COMB_BIT);
76  } else {
77  SPINDLE_TCCRA_REGISTER |= (1<<SPINDLE_COMB_BIT);
78  }
79 }
80 
82 uint16_t spindle_compute_pwm_value(float rpm)
83 {
84  uint16_t pwm_value;
85  rpm *= (0.010*sys.spindle_speed_ovr);
86 // Calculate PWM register value based on rpm max/min settings and programmed rpm.
87  if ((settings.rpm_min >= settings.rpm_max) || (rpm >= settings.rpm_max)) {
88 // No PWM range possible. Set simple on/off spindle control pin state.
90  pwm_value = SPINDLE_PWM_MAX_VALUE;
91  } else if (rpm <= settings.rpm_min) {
92  if (rpm == 0.0) {
93  sys.spindle_speed = 0.0;
94  pwm_value = SPINDLE_PWM_OFF_VALUE;
95  } else {
97  pwm_value = SPINDLE_PWM_MIN_VALUE;
98  }
99  } else {
100 // Compute intermediate PWM value with linear spindle speed model.
101 //
103  sys.spindle_speed = rpm;
104  pwm_value = floor((rpm-settings.rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE;
105  }
106  return(pwm_value);
107 }
108 
110 // Called by g-code parser spindle_sync(), parking retract and restore, g-code program end,
111 // sleep, and spindle stop override.
112 void spindle_set_state(uint8_t state, float rpm)
113 {
114  if (sys.abort) { return; }
115  if (state == SPINDLE_DISABLE) {
116 
117  sys.spindle_speed = 0.0;
118  spindle_stop();
119 
120  } else {
121 
122  if (state == SPINDLE_ENABLE_CW) {
123  SPINDLE_DIRECTION_PORT &= ~(1<<SPINDLE_DIRECTION_BIT);
124  } else {
125  SPINDLE_DIRECTION_PORT |= (1<<SPINDLE_DIRECTION_BIT);
126  }
127 
128 //
131  if (state == SPINDLE_ENABLE_CCW) { rpm = 0.0; }
132  }
134 
135  #ifdef INVERT_SPINDLE_ENABLE_PIN
136  SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
137  #else
138  SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
139  #endif
140 
141  }
142 
143  sys.report_ovr_counter = 0;
144 }
145 
147 // if an abort or check-mode is active.
148 void spindle_sync(uint8_t state, float rpm)
149 {
150  if (sys.state == STATE_CHECK_MODE) { return; }
152  spindle_set_state(state,rpm);
153 }
void spindle_set_state(uint8_t state, float rpm)
Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled...
void spindle_init()
Initializes spindle pins and hardware PWM, if enabled.
#define SPINDLE_ENABLE_CCW
NOTE: Uses planner condition bit flag)
Definition: gcode.h:108
uint8_t spindle_speed_ovr
Spindle speed value in percent.
Definition: system.h:121
uint16_t spindle_compute_pwm_value(float rpm)
Called by spindle_set_state() and step segment generator. Keep routine small and efficient.
#define SPINDLE_STATE_DISABLE
Must be zero.
float rpm_max
Definition: settings.h:89
void protocol_buffer_synchronize()
Block until all buffered steps are executed or in a cycle state. Works with feed hold.
Definition: protocol.c:177
uint8_t state
Tracks the current system state of Grbl.
Definition: system.h:112
uint8_t spindle_get_state()
Returns current spindle output state. Overrides may alter it from programmed states.
#define BITFLAG_LASER_MODE
Definition: settings.h:36
void spindle_stop()
Disables the spindle and sets PWM output to zero when PWM variable spindle speed is enabled...
#define SPINDLE_DISABLE
Modal Group M7: Spindle control.
Definition: gcode.h:105
uint8_t abort
System abort flag. Forces exit back to main loop for reset.
Definition: system.h:113
#define SPINDLE_STATE_CW
uint8_t flags
Contains default boolean settings.
Definition: settings.h:92
#define STATE_CHECK_MODE
G-code check mode. Locks out planner and motion only.
Definition: system.h:74
system_t sys
Declare system global variable structure.
Definition: main.c:25
uint8_t report_ovr_counter
Tracks when to add override data to status reports.
Definition: system.h:123
void spindle_set_speed(uint16_t pwm_value)
Sets spindle speed PWM output and enable pin, if configured. Called by spindle_set_state() ...
#define SPINDLE_ENABLE_CW
M3 (.
Definition: gcode.h:106
#define bit_isfalse(x, mask)
Definition: nuts_bolts.h:61
float rpm_min
Definition: settings.h:90
settings_t settings
Definition: settings.c:24
float spindle_speed
Definition: system.h:125
#define SPINDLE_STATE_CCW
void spindle_sync(uint8_t state, float rpm)
G-code parser entry-point for setting spindle state. Forces a planner buffer sync and bails...
#define bit_istrue(x, mask)
Definition: nuts_bolts.h:60