Cleaned up variable spindle output (PWM). Code and config comments.

- Variable spindle speed output as a configuration option. Thanks
@EliteEng! When enabled, the Z-limit (D11) and spindle enable(D12) pins
switch to allow access to the hardware PWM output on pin D11.
Otherwise, everything should work as it does.

- Removed option for inverting the spindle and coolant enable pins.
This is a safety hazard, especially for the spindle. When Grbl
initializes, all pins are momentarily low until it finishes booting. If
an invert is enabled, this means the spindles can be energized briefly
during this time. If users need signal inversion, it’s recommended to
just wire in an inversion circuit instead.

- Cleared out references to spindle variable output in terms of step
signal. This isn’t complete and requires more deliberation before
installing.

- Cleared up and cleaned up some code and config comments.
This commit is contained in:
Sonny Jeon 2014-01-04 12:12:44 -07:00
parent e7cd94e2bc
commit 8b5f306851
6 changed files with 183 additions and 206 deletions

View File

@ -86,10 +86,24 @@
// acceleration, particularly noticeable on machines that run at very high feedrates, but may negatively
// impact performance. The correct value for this parameter is machine dependent, so it's advised to
// set this only as high as needed. Approximate successful values can widely range from 50 to 200 or more.
// NOTE: Changing this value also changes the execution time of a segment in the step segment buffer.
// When increasing this value, this stores less overall time in the segment buffer and vice versa. Make
// certain the step segment buffer is increased/decreased to account for these changes.
#define ACCELERATION_TICKS_PER_SECOND 100
#define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
#define ENABLE_SOFTWARE_DEBOUNCE
// Adaptive Multi-Axis Step Smoothing (AMASS) is an advanced feature that does what its name implies,
// smoothing the stepping of multi-axis motions. This feature smooths motion particularly at low step
// frequencies below 10kHz, where the aliasing between axes of multi-axis motions can cause audible
// noise and shake your machine. At even lower step frequencies, AMASS adapts and provides even better
// step smoothing. See stepper.c for more details on the AMASS system works.
#define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable.
// Enables variable spindle output voltage for different RPM values. On the Arduino Uno, the spindle
// enable pin will output 5V for maximum RPM with 256 intermediate levels and 0V when disabled.
// NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch!
// The hardware PWM output on pin D11 is required for variable spindle output voltages.
// #define VARIABLE_SPINDLE // Default disabled. Uncomment to enable.
// #define SPINDLE_MAX_RPM 1000 // Max spindle RPM. This value is equal to 100% Duty Cycle on the PWM.
// Minimum planner junction speed. Sets the default minimum junction speed the planner plans to at
// every buffer block junction, except for starting from rest and end of the buffer, which are always
@ -168,6 +182,14 @@
// case, please report any successes to grbl administrators!
// #define ENABLE_XONXOFF // Default disabled. Uncomment to enable.
// A simple software debouncing feature for hard limit switches. When enabled, the interrupt monitoring
// the hard limit switch pins will enable the Arduino's watchdog timer to re-check the limit pin state
// after a delay of about 32msec. This can help with CNC machines with problematic false triggering of
// their hard limit switches, but it WILL NOT fix issues with electrical interference on the signal
// cables from external sources. It's recommended to first use shielded signal cables that are grounded
// (old USB/computer cables work well) and wire in a low-pass circuit into each limit pin.
// #define ENABLE_SOFTWARE_DEBOUNCE // Default disabled. Uncomment to enable.
// ---------------------------------------------------------------------------------------
// TODO: Install compile-time option to send numeric status codes rather than strings.

View File

@ -27,29 +27,24 @@
static uint8_t current_coolant_mode;
void coolant_init()
{
current_coolant_mode = COOLANT_DISABLE;
#if ENABLE_M7
COOLANT_FLOOD_DDR |= (1 << COOLANT_FLOOD_BIT);
#ifdef ENABLE_M7
COOLANT_MIST_DDR |= (1 << COOLANT_MIST_BIT);
#endif
COOLANT_FLOOD_DDR |= (1 << COOLANT_FLOOD_BIT);
coolant_stop();
}
void coolant_stop()
{
#ifdef INVERT_COOLANT
COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT);
#ifdef ENABLE_M7
COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
#endif
COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
#else
#ifdef ENABLE_M7
COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT);
#endif
COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT);
#endif
COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT);
#endif
}
@ -59,19 +54,13 @@ void coolant_run(uint8_t mode)
{
plan_synchronize(); // Ensure coolant turns on when specified in program.
if (mode == COOLANT_FLOOD_ENABLE) {
#ifdef INVERT_COOLANT
COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT);
#else
COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
#endif
#ifdef ENABLE_M7
} else if (mode == COOLANT_MIST_ENABLE) {
#ifdef INVERT_COOLANT
COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT);
#else
COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
#endif
#endif
COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
#ifdef ENABLE_M7
} else if (mode == COOLANT_MIST_ENABLE) {
COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
#endif
} else {
coolant_stop();
}

217
cpu_map.h
View File

@ -28,94 +28,82 @@
#ifndef cpu_map_h
#define cpu_map_h
//----------------------------------------------------------------------------------------
#ifdef CPU_MAP_ATMEGA328P // (Arduino Uno) Officially supported by Grbl.
// Serial port pins
// Define serial port pins and interrupt vectors.
#define SERIAL_RX USART_RX_vect
#define SERIAL_UDRE USART_UDRE_vect
// Start of PWM & Stepper Enabled Spindle
// #define VARIABLE_SPINDLE // comment this out to disable PWM & Stepper on the spindle
// NOTE: All step bit and direction pins must be on the same port.
#define STEPPING_DDR DDRD
#define STEPPING_PORT PORTD
#define X_STEP_BIT 2 // Uno Digital Pin 2
#define Y_STEP_BIT 3 // Uno Digital Pin 3
#define Z_STEP_BIT 4 // Uno Digital Pin 4
#define STEP_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
// Define step pulse output pins. NOTE: All step bit pins must be on the same port.
#define STEPPING_DDR DDRD
#define STEPPING_PORT PORTD
#define X_STEP_BIT 2 // Uno Digital Pin 2
#define Y_STEP_BIT 3 // Uno Digital Pin 3
#define Z_STEP_BIT 4 // Uno Digital Pin 4
#define STEP_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
#define DIRECTION_DDR DDRD
#define DIRECTION_PORT PORTD
#define X_DIRECTION_BIT 5 // Uno Digital Pin 5
#define Y_DIRECTION_BIT 6 // Uno Digital Pin 6
#define Z_DIRECTION_BIT 7 // Uno Digital Pin 7
#define DIRECTION_MASK ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
// Define step direction output pins. NOTE: All direction pins must be on the same port.
#define DIRECTION_DDR DDRD
#define DIRECTION_PORT PORTD
#define X_DIRECTION_BIT 5 // Uno Digital Pin 5
#define Y_DIRECTION_BIT 6 // Uno Digital Pin 6
#define Z_DIRECTION_BIT 7 // Uno Digital Pin 7
#define DIRECTION_MASK ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
// Define stepper driver enable/disable output pin.
#define STEPPERS_DISABLE_DDR DDRB
#define STEPPERS_DISABLE_PORT PORTB
#define STEPPERS_DISABLE_BIT 0 // Uno Digital Pin 8
#define STEPPERS_DISABLE_MASK (1<<STEPPERS_DISABLE_BIT)
#ifdef VARIABLE_SPINDLE // Z LImit has been disabled to make room for the Spindle PWM
// NOTE: All limit bit pins must be on the same port
#define LIMIT_DDR DDRB
#define LIMIT_PIN PINB
#define LIMIT_PORT PORTB
#define X_LIMIT_BIT 1 // Uno Digital Pin 9
#define Y_LIMIT_BIT 2 // Uno Digital Pin 9
#define Z_LIMIT_BIT 2 // Uno Digital Pin 11
#define LIMIT_INT PCIE0 // Pin change interrupt enable pin
#define LIMIT_INT_vect PCINT0_vect
#define LIMIT_PCMSK PCMSK0 // Pin change interrupt register
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)) // All limit bits
#define STEPPERS_DISABLE_MASK (1<<STEPPERS_DISABLE_BIT)
// Define homing/hard limit switch input pins and limit interrupt vectors.
// NOTE: All limit bit pins must be on the same port, but not on a port with other input pins (pinout).
#define LIMIT_DDR DDRB
#define LIMIT_PIN PINB
#define LIMIT_PORT PORTB
#define X_LIMIT_BIT 1 // Uno Digital Pin 9
#define Y_LIMIT_BIT 2 // Uno Digital Pin 10
#ifdef VARIABLE_SPINDLE // Z Limit pin and spindle enabled swapped to access hardware PWM on Pin 11.
#define Z_LIMIT_BIT 4 // Uno Digital Pin 12
#else
// NOTE: All limit bit pins must be on the same port
#define LIMIT_DDR DDRB
#define LIMIT_PIN PINB
#define LIMIT_PORT PORTB
#define X_LIMIT_BIT 1 // Uno Digital Pin 9
#define Y_LIMIT_BIT 2 // Uno Digital Pin 10
#define Z_LIMIT_BIT 3 // Uno Digital Pin 11
#define LIMIT_INT PCIE0 // Pin change interrupt enable pin
#define LIMIT_INT_vect PCINT0_vect
#define LIMIT_PCMSK PCMSK0 // Pin change interrupt register
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
#define Z_LIMIT_BIT 3 // Uno Digital Pin 11
#endif
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
#define LIMIT_INT PCIE0 // Pin change interrupt enable pin
#define LIMIT_INT_vect PCINT0_vect
#define LIMIT_PCMSK PCMSK0 // Pin change interrupt register
// WARNING if INVERT_SPINDLE is defined the pin will be LOW(Active) on reset of controller until spindle_init() is called.
// this should only be a very short period of time but will energise the spindle.
// #define INVERT_SPINDLE // This will INVERT the Spindle LOW=Active
// END WARNING
#define SPINDLE_ENABLE_DDR DDRB
#define SPINDLE_ENABLE_PORT PORTB
#define SPINDLE_ENABLE_BIT 4 // Uno Digital Pin 12
// Define spindle enable and spindle direction output pins.
#define SPINDLE_ENABLE_DDR DDRB
#define SPINDLE_ENABLE_PORT PORTB
#ifdef VARIABLE_SPINDLE // Z Limit pin and spindle enabled swapped to access hardware PWM on Pin 11.
#define SPINDLE_ENABLE_BIT 3 // Uno Digital Pin 11
#else
#define SPINDLE_ENABLE_BIT 4 // Uno Digital Pin 12
#endif
#define SPINDLE_DIRECTION_DDR DDRB
#define SPINDLE_DIRECTION_PORT PORTB
#define SPINDLE_DIRECTION_BIT 5 // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
// WARNING if INVERT_COOLANT is defined the pin will be LOW(Active) on reset of controller until coolant_init() is called.
// this should only be a very short period of time but will energise the coolant pump.
// #define INVERT_COOLANT // This will INVERT the Coolant LOW=Active
// END WARNING
// Define flood and mist coolant enable output pins.
// NOTE: Uno analog pins 4 and 5 are reserved for an i2c interface, and may be installed at
// a later date if flash and memory space allows.
#define COOLANT_FLOOD_DDR DDRC
#define COOLANT_FLOOD_PORT PORTC
#define COOLANT_FLOOD_BIT 3 // Uno Analog Pin 3
// NOTE: Uno analog pins 4 and 5 are reserved for an i2c interface, and may be installed at
// a later date if flash and memory space allows.
// #define ENABLE_M7 // Mist coolant disabled by default. Uncomment to enable.
#ifdef ENABLE_M7
#ifdef ENABLE_M7 // Mist coolant disabled by default. See config.h to enable/disable.
#define COOLANT_MIST_DDR DDRC
#define COOLANT_MIST_PORT PORTC
#define COOLANT_MIST_BIT 4 // Uno Analog Pin 4
#endif
// NOTE: All pinouts pins must be on the same port, but cannot be on same port as limit pins.
// Define user-control pinouts (cycle start, reset, feed hold) input pins.
// NOTE: All pinouts pins must be on the same port and not on a port with other input pins (limits).
#define PINOUT_DDR DDRC
#define PINOUT_PIN PINC
#define PINOUT_PORT PORTC
@ -128,35 +116,28 @@
#define PINOUT_MASK ((1<<PIN_RESET)|(1<<PIN_FEED_HOLD)|(1<<PIN_CYCLE_START))
#ifdef VARIABLE_SPINDLE
// Advanced Configuration Below You should not need to touch these variables
#define TCCRA_REGISTER TCCR2A
#define TCCRB_REGISTER TCCR2B
#define OCR_REGISTER OCR2A
#define SPINDLE_IS_PWM // Uncomment this if your Spindle uses PWM ie. DC Motor
#ifdef SPINDLE_IS_PWM
#define SPINDLE_MAX_RPM 255 // Max RPM of your spindle - This value is equal to 100% Duty Cycle on the PWM
#endif
// Advanced Configuration Below You should not need to touch these variables
//Set Timer up to use TIMER4 OCR4B which is attached to Digital Pin 7
#define TCCRA_REGISTER TCCR2A
#define TCCRB_REGISTER TCCR2B
#define OCR_REGISTER OCR2A
#define COMB_BIT COM2A1
#define WAVE0_REGISTER WGM20
#define WAVE1_REGISTER WGM21
#define WAVE2_REGISTER WGM22
#define WAVE3_REGISTER WGM23
#define SPINDLE_PWM_DDR DDRB
#define SPINDLE_PWM_PORT PORTB
#define SPINDLE_PWM_BIT 3 // UNO Digital Pin 11
#define COMB_BIT COM2A1
#define WAVE0_REGISTER WGM20
#define WAVE1_REGISTER WGM21
#define WAVE2_REGISTER WGM22
#define WAVE3_REGISTER WGM23
// NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
#define SPINDLE_PWM_DDR SPINDLE_ENABLE_DDR
#define SPINDLE_PWM_PORT SPINDLE_ENABLE_PORT
#define SPINDLE_PWM_BIT SPINDLE_ENABLE_BIT // Shared with SPINDLE_ENABLE.
#endif // End of VARIABLE_SPINDLE
#endif
#endif
#ifdef CPU_MAP_ATMEGA2560 // (Arduino Mega 2560) Working @EliteEng
//----------------------------------------------------------------------------------------
#ifdef CPU_MAP_ATMEGA2560 // (Arduino Mega 2560) Working @EliteEng
// Serial port pins
#define SERIAL_RX USART0_RX_vect
@ -168,7 +149,7 @@
//#define BLOCK_BUFFER_SIZE 36
//#define LINE_BUFFER_SIZE 100
// NOTE: All step pins must be on the same port.
// Define step pulse output pins. NOTE: All step bit pins must be on the same port.
#define STEPPING_DDR DDRA
#define STEPPING_PORT PORTA
#define STEPPING_PIN PINA
@ -177,7 +158,7 @@
#define Z_STEP_BIT 4 // MEGA2560 Digital Pin 26
#define STEP_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
// NOTE: All direction pins must be on the same port.
// Define step direction output pins. NOTE: All direction pins must be on the same port.
#define DIRECTION_DDR DDRA
#define DIRECTION_PORT PORTA
#define DIRECTION_PIN PINA
@ -186,6 +167,7 @@
#define Z_DIRECTION_BIT 7 // MEGA2560 Digital Pin 29
#define DIRECTION_MASK ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
// Define stepper driver enable/disable output pin.
#define STEPPERS_DISABLE_DDR DDRB
#define STEPPERS_DISABLE_PORT PORTB
#define STEPPERS_DISABLE_BIT 7 // MEGA2560 Digital Pin 13
@ -203,36 +185,28 @@
#define LIMIT_PCMSK PCMSK0 // Pin change interrupt register
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
// WARNING if INVERT_SPINDLE is defined the pin will be LOW(Active) on reset of controller until spindle_init() is called.
// this should only be a very short period of time but will energise the spindle.
// #define INVERT_SPINDLE // This will INVERT the Spindle LOW=Active
// END WARNING
// Define spindle enable and spindle direction output pins.
#define SPINDLE_ENABLE_DDR DDRH
#define SPINDLE_ENABLE_PORT PORTH
#define SPINDLE_ENABLE_BIT 3 // MEGA2560 Digital Pin 6
#define SPINDLE_DIRECTION_DDR DDRE
#define SPINDLE_DIRECTION_PORT PORTE
#define SPINDLE_DIRECTION_BIT 3 // MEGA2560 Digital Pin 5
// WARNING if INVERT_COOLANT is defined the pin will be LOW(Active) on reset of controller until coolant_init() is called.
// this should only be a very short period of time but will energise the coolant pump.
// #define INVERT_COOLANT // This will INVERT the Coolant LOW=Active
// END WARNING
// Define flood and mist coolant enable output pins.
// NOTE: Uno analog pins 4 and 5 are reserved for an i2c interface, and may be installed at
// a later date if flash and memory space allows.
#define COOLANT_FLOOD_DDR DDRH
#define COOLANT_FLOOD_PORT PORTH
#define COOLANT_FLOOD_BIT 5 // MEGA2560 Digital Pin 8
// #define ENABLE_M7 // Mist coolant disabled by default. Uncomment to enable.
#ifdef ENABLE_M7
#ifdef ENABLE_M7 // Mist coolant disabled by default. See config.h to enable/disable.
#define COOLANT_MIST_DDR DDRH
#define COOLANT_MIST_PORT PORTH
#define COOLANT_MIST_BIT 6 // MEGA2560 Digital Pin 9
#endif
// NOTE: All pinouts pins must be on the same port and cannot be on same port as limit pins.
// Define user-control pinouts (cycle start, reset, feed hold) input pins.
// NOTE: All pinouts pins must be on the same port and not on a port with other input pins (limits).
#define PINOUT_DDR DDRK
#define PINOUT_PIN PINK
#define PINOUT_PORT PORTK
@ -245,40 +219,31 @@
#define PINOUT_MASK ((1<<PIN_RESET)|(1<<PIN_FEED_HOLD)|(1<<PIN_CYCLE_START))
// Start of PWM & Stepper Enabled Spindle
// #define VARIABLE_SPINDLE // comment this out to disable PWM & Stepper on the spindle
#ifdef VARIABLE_SPINDLE
// Advanced Configuration Below You should not need to touch these variables
// Set Timer up to use TIMER4 OCR4B which is attached to Digital Pin 7
#define TCCRA_REGISTER TCCR2A
#define TCCRB_REGISTER TCCR2B
#define OCR_REGISTER OCR2B
//#define SPINDLE_IS_STEPPER // Uncomment this if your Spindle is a Stepper Motor
#define SPINDLE_IS_PWM // Uncomment this if your Spindle uses PWM ie. DC Motor
#ifdef SPINDLE_IS_PWM
#define SPINDLE_MAX_RPM 255 // Max RPM of your spindle
#endif
// Advanced Configuration Below You should not need to touch these variables
//Set Timer up to use TIMER4 OCR4B which is attached to Digital Pin 7
#define TCCRA_REGISTER TCCR2A
#define TCCRB_REGISTER TCCR2B
#define OCR_REGISTER OCR2B
#define COMB_BIT COM2B1
#define WAVE0_REGISTER WGM20
#define WAVE1_REGISTER WGM21
#define WAVE2_REGISTER WGM22
#define WAVE3_REGISTER WGM23
#define SPINDLE_PWM_DDR DDRH
#define SPINDLE_PWM_PORT PORTH
#define SPINDLE_PWM_BIT 6 // MEGA2560 Digital Pin 9
#define COMB_BIT COM2B1
#define WAVE0_REGISTER WGM20
#define WAVE1_REGISTER WGM21
#define WAVE2_REGISTER WGM22
#define WAVE3_REGISTER WGM23
#define SPINDLE_PWM_DDR DDRH
#define SPINDLE_PWM_PORT PORTH
#define SPINDLE_PWM_BIT 6 // MEGA2560 Digital Pin 9
#endif // End of VARIABLE_SPINDLE
#endif
#endif
//----------------------------------------------------------------------------------------
/*
#ifdef CPU_MAP_CUSTOM_PROC
// For a custom pin map or different processor, copy and paste one of the default cpu map
// settings above and modify it to your needs. Then, make sure the defined name is also
// changed in the config.h file.
#endif

View File

@ -55,7 +55,7 @@ void limits_init()
#ifdef ENABLE_SOFTWARE_DEBOUNCE
MCUSR &= ~(1<<WDRF);
WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = (1<<WDP0);
WDTCSR = (1<<WDP0); // Set time-out at ~32msec.
#endif
}

View File

@ -25,73 +25,71 @@
static uint8_t current_direction;
static uint16_t current_rpm;
static uint8_t current_pwm;
void spindle_init()
{
current_direction = 0;
SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT);
SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT);
#ifdef VARIABLE_SPINDLE
SPINDLE_PWM_DDR |= (1<<SPINDLE_PWM_BIT);
#endif
// On the Uno, spindle enable and PWM are shared. Other CPUs have seperate enable pin.
#ifdef VARIABLE_SPINDLE
SPINDLE_PWM_DDR |= (1<<SPINDLE_PWM_BIT);
#ifndef CPU_MAP_ATMEGA328P
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
#endif
#else
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
#endif
spindle_stop();
}
void spindle_stop()
{
#ifdef INVERT_SPINDLE
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
#else
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
#endif
#ifdef VARIABLE_SPINDLE
TCCRA_REGISTER &= ~(1<<COMB_BIT);
#endif
// On the Uno, spindle enable and PWM are shared. Other CPUs have seperate enable pin.
#ifdef VARIABLE_SPINDLE
TCCRA_REGISTER &= ~(1<<COMB_BIT); // Disable PWM. Output voltage is zero.
#ifndef CPU_MAP_ATMEGA328P
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
#endif
#else
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
#endif
}
void spindle_run(int8_t direction, uint16_t rpm) {
if ((direction != current_direction) || (rpm != current_rpm)) {
plan_synchronize();
if (direction) {
if (direction > 0) {
SPINDLE_DIRECTION_PORT &= ~(1<<SPINDLE_DIRECTION_BIT);
} else {
SPINDLE_DIRECTION_PORT |= (1<<SPINDLE_DIRECTION_BIT);
}
#ifdef VARIABLE_SPINDLE
#ifdef SPINDLE_IS_PWM
void spindle_run(int8_t direction, uint16_t rpm)
{
if ((direction != current_direction) || (rpm != current_rpm)) {
plan_synchronize(); // Empty planner buffer to ensure spindle is updated as programmed.
if (direction) {
if (direction > 0) {
SPINDLE_DIRECTION_PORT &= ~(1<<SPINDLE_DIRECTION_BIT);
} else {
SPINDLE_DIRECTION_PORT |= (1<<SPINDLE_DIRECTION_BIT);
}
TCCRA_REGISTER = (1<<COMB_BIT) | (1<<WAVE1_REGISTER) | (1<<WAVE0_REGISTER);
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x02; // set to 1/8 Prescaler
current_pwm = floor((((float) rpm / (float) SPINDLE_MAX_RPM ) * 255.0) + 0.5);
OCR_REGISTER = current_pwm;
#endif
#endif
#ifdef INVERT_SPINDLE
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
#else
#ifdef VARIABLE_SPINDLE
TCCRA_REGISTER = (1<<COMB_BIT) | (1<<WAVE1_REGISTER) | (1<<WAVE0_REGISTER);
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x02; // set to 1/8 Prescaler
if (rpm > SPINDLE_MAX_RPM) { rpm = SPINDLE_MAX_RPM; } // Prevent overflow.
uint8_t current_pwm = floor((((float) rpm / (float) SPINDLE_MAX_RPM ) * 255.0) + 0.5);
OCR_REGISTER = current_pwm;
#ifndef CPU_MAP_ATMEGA328P // On the Uno, spindle enable and PWM are shared.
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
#endif
#else
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
#endif
#endif
} else {
spindle_stop();
}
current_direction = direction;
current_rpm = rpm;
spindle_stop();
}
current_direction = direction;
current_rpm = rpm;
}
}
uint8_t spindle_pwm()
{
return current_pwm;
}
void spindle_pwm_update(uint8_t pwm)
{
OCR_REGISTER = pwm;
}
#endif

View File

@ -24,10 +24,13 @@
#include <avr/io.h>
// Initializes spindle pins and hardware PWM, if enabled.
void spindle_init();
// Sets spindle direction and spindle rpm via PWM, if enabled.
void spindle_run(int8_t direction, uint16_t rpm);
// Kills spindle.
void spindle_stop();
uint8_t spindle_pwm();
void spindle_pwm_update(uint8_t pwm);
#endif