Added comments throughout code

This commit is contained in:
B. Perry 2019-04-29 13:47:11 -06:00
parent ac6817f7e2
commit a7ba369987
11 changed files with 209 additions and 206 deletions

View File

@ -22,11 +22,11 @@
void delay_init()
{
LPC_TIM3->CTCR = 0; // timer mode
LPC_TIM3->PR = 0; // no prescale
LPC_TIM3->MCR = 0; // no MR actions
LPC_TIM3->CCR = 0; // no capture
LPC_TIM3->EMR = 0; // no external match
LPC_TIM3->TCR = 0b10; // reset
LPC_TIM3->TCR = 0b01; // enable
LPC_TIM3->CTCR = 0; // Count Control (0=TimerMode, 1-3=EdgeCounterMode)
LPC_TIM3->PR = 0; // no Prescale (TC increments ever PR+1 clocks)
LPC_TIM3->MCR = 0; // no Match Control actions
LPC_TIM3->CCR = 0; // no Capture Control actions
LPC_TIM3->EMR = 0; // no External Match (controls external match pins)
LPC_TIM3->TCR = 0b10; // reset Timer Control (0b10=Reset, 0b01=Enable)
LPC_TIM3->TCR = 0b01; // enable Timer Control (0b10=Reset, 0b01=Enable)
}

View File

@ -25,37 +25,38 @@ static constexpr unsigned flash_addr = 0xF000; // Last 4k sec
static constexpr unsigned flash_size = 1024; // Only using 1k of a 4k sector
static char *flash_memory = (char *)flash_addr; // Flash memory
static char flash_buffer[flash_size] __attribute__((aligned(4))); // Copy of flash memory
using Iap = void(unsigned[], unsigned[]); // IAP entry point
static const Iap *iap = (Iap *)0x1FFF1FF1; // IAP entry point
using Iap = void(unsigned[], unsigned[]); // IAP entry point function
static const Iap *iap = (Iap *)0x1FFF1FF1; // IAP entry point address
void eeprom_init()
{
memcpy(flash_buffer, flash_memory, flash_size);
memcpy(flash_buffer, flash_memory, flash_size); // Copy flash memory into local flash buffer
}
void eeprom_commit()
{
if (!memcmp(flash_buffer, flash_memory, flash_size))
return;
return; // No changes to commit
unsigned prepCommand[5] = {
50,
flash_sector,
flash_sector,
50, // Prepare sector(s) for write operation
flash_sector, // Start sector
flash_sector, // End sector
};
unsigned eraseCommand[5] = {
52,
flash_sector,
flash_sector,
SystemCoreClock / 1000,
52, // Erase sector(s)
flash_sector, // Start sector
flash_sector, // End sector
SystemCoreClock / 1000, // CPU clock frequency in kHz
};
unsigned writeCommand[5] = {
51,
flash_addr,
(unsigned)flash_buffer,
flash_size,
SystemCoreClock / 1000,
51, // Copy RAM to Flash
flash_addr, // Destination flash address (256-byte boundary)
(unsigned)flash_buffer, // Source RAM address (word boundary)
flash_size, // Number of bytes to write (must be: 256, 512, 1024, 4096)
SystemCoreClock / 1000, // CPU clock frequency in kHz
};
unsigned output[5];
// Run In-Application Programming (IAP) routines
iap(prepCommand, output);
iap(eraseCommand, output);
iap(prepCommand, output);

View File

@ -125,7 +125,7 @@
// #define HOMING_CYCLE_1 (1<<Y_AXIS) // COREXY COMPATIBLE: Then home Y
// Number of homing cycles performed after when the machine initially jogs to limit switches.
// This help in preventing overshoot and should improve repeatability. This value should be one or
// This helps in preventing overshoot and should improve repeatability. This value should be one or
// greater.
#define N_HOMING_LOCATE_CYCLE 1 // Integer (1-128)

View File

@ -63,7 +63,7 @@
#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
#define Z_LIMIT_BIT 4 // Uno Digital Pin 12
#else
#define Z_LIMIT_BIT 3 // Uno Digital Pin 11
#endif
@ -96,9 +96,9 @@
#define COOLANT_FLOOD_DDR DDRC
#define COOLANT_FLOOD_PORT PORTC
#define COOLANT_FLOOD_BIT 3 // Uno Analog Pin 3
#define COOLANT_MIST_DDR DDRC
#define COOLANT_MIST_PORT PORTC
#define COOLANT_MIST_BIT 4 // Uno Analog Pin 4
#define COOLANT_MIST_DDR DDRC
#define COOLANT_MIST_PORT PORTC
#define COOLANT_MIST_BIT 4 // Uno Analog Pin 4
// Define user-control controls (cycle start, reset, feed hold) input pins.
// NOTE: All CONTROLs pins must be on the same port and not on a port with other input pins (limits).
@ -130,10 +130,10 @@
#endif
#define SPINDLE_PWM_OFF_VALUE 0
#define SPINDLE_PWM_RANGE (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_OCR_REGISTER OCR2A
#define SPINDLE_COMB_BIT COM2A1
#define SPINDLE_COMB_BIT COM2A1
// Prescaled, 8-bit Fast PWM mode.
#define SPINDLE_TCCRA_INIT_MASK ((1<<WGM20) | (1<<WGM21)) // Configures fast PWM mode.
@ -143,11 +143,11 @@
#define SPINDLE_TCCRB_INIT_MASK (1<<CS22) // 1/64 prescaler -> 0.98kHz (J-tech laser)
// NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
#define SPINDLE_PWM_DDR DDRB
#define SPINDLE_PWM_DDR DDRB
#define SPINDLE_PWM_PORT PORTB
#define SPINDLE_PWM_BIT 3 // Uno Digital Pin 11
#define SPINDLE_PWM_BIT 3 // Uno Digital Pin 11
#endif
#endif // end of CPU_MAP_ATMEGA328P
#ifdef CPU_MAP_SMOOTHIEBOARD // (Smoothieboards)
@ -190,7 +190,7 @@
#define LIMIT_PORT LPC_GPIO1->FIOPIN
#define X_LIMIT_BIT 24 // X-MIN=24, X-MAX=25
#define Y_LIMIT_BIT 26 // Y-MIN=26, Y-MAX=27
#define Z_LIMIT_BIT 28 // Z-MIN=28, Z-MAX=29
#define Z_LIMIT_BIT 28 // Z-MIN=28, Z-MAX=29
#define A_LIMIT_BIT 29 // reuse p1.29
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)|(1<<A_LIMIT_BIT)) // All limit bits
@ -200,7 +200,7 @@
#define COOLANT_FLOOD_BIT 4 // SMALL MOSFET Q8 (P2.4)
#define COOLANT_MIST_DDR LPC_GPIO2->FIODIR
#define COOLANT_MIST_PORT LPC_GPIO2->FIOPIN
#define COOLANT_MIST_BIT 6 // SMALL MOSFET Q9 (P2.6)
#define COOLANT_MIST_BIT 6 // SMALL MOSFET Q9 (P2.6)
#define ENABLE_M7 // enables COOLANT MIST
// Define user-control controls (cycle start, reset, feed hold) input pins.
@ -252,11 +252,11 @@
#endif
//#define SPINDLE_PWM_OFF_VALUE 0 // Defined in config.h
#define SPINDLE_PWM_RANGE (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_OCR_REGISTER OCR2A
#define SPINDLE_COMB_BIT COM2A1
#endif
#define SPINDLE_COMB_BIT COM2A1
#endif // end of CPU_MAP_SMOOTHIEBOARD
#ifdef CPU_MAP_C3D_REMIX // (Cohesion3D Remix Boards)
@ -299,7 +299,7 @@
#define LIMIT_PORT LPC_GPIO1->FIOPIN
#define X_LIMIT_BIT 24 // X-MIN=24, X-MAX=25
#define Y_LIMIT_BIT 26 // Y-MIN=26, Y-MAX=27
#define Z_LIMIT_BIT 28 // Z-MIN=28, Z-MAX=29
#define Z_LIMIT_BIT 28 // Z-MIN=28, Z-MAX=29
#define A_LIMIT_BIT 29 // reuse p1.29 from Z-MAX
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)|(1<<A_LIMIT_BIT)) // All limit bits
@ -355,11 +355,11 @@
#endif
//#define SPINDLE_PWM_OFF_VALUE 0 // Defined in config.h
#define SPINDLE_PWM_RANGE (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_OCR_REGISTER OCR2A
#define SPINDLE_COMB_BIT COM2A1
#endif
#define SPINDLE_COMB_BIT COM2A1
#endif // end of CPU_MAP_C3D_REMIX
#ifdef CPU_MAP_C3D_MINI // (Cohesion3D Mini Boards)
@ -402,7 +402,7 @@
#define LIMIT_PORT LPC_GPIO1->FIOPIN
#define X_LIMIT_BIT 24 // X-MIN=24, X-MAX=25
#define Y_LIMIT_BIT 26 // Y-MIN=26, Y-MAX=27
#define Z_LIMIT_BIT 28 // Z-MIN=28, Z-MAX=29
#define Z_LIMIT_BIT 28 // Z-MIN=28, Z-MAX=29
#define A_LIMIT_BIT 29 // reuse p1.29 from Z-MAX
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)|(1<<A_LIMIT_BIT)) // All limit bits
@ -458,11 +458,11 @@
#endif
//#define SPINDLE_PWM_OFF_VALUE 0 // Defined in config.h
#define SPINDLE_PWM_RANGE (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_OCR_REGISTER OCR2A
#define SPINDLE_COMB_BIT COM2A1
#endif
#define SPINDLE_COMB_BIT COM2A1
#endif // end of CPU_MAP_C3D_MINI
#ifdef CPU_MAP_MKS_SBASE // (MKS SBASE Boards)
@ -505,7 +505,7 @@
#define LIMIT_PORT LPC_GPIO1->FIOPIN
#define X_LIMIT_BIT 24 // X-MIN=24, X-MAX=25
#define Y_LIMIT_BIT 26 // Y-MIN=26, Y-MAX=27
#define Z_LIMIT_BIT 28 // Z-MIN=28, Z-MAX=29
#define Z_LIMIT_BIT 28 // Z-MIN=28, Z-MAX=29
#define A_LIMIT_BIT 29 // reuse p1.29
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)|(1<<A_LIMIT_BIT)) // All limit bits
@ -573,11 +573,11 @@
#endif
//#define SPINDLE_PWM_OFF_VALUE 0 // Defined in config.h
#define SPINDLE_PWM_RANGE (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_OCR_REGISTER OCR2A
#define SPINDLE_COMB_BIT COM2A1
#endif
#define SPINDLE_COMB_BIT COM2A1
#endif // end of CPU_MAP_MKS_SBASE
#ifdef CPU_MAP_AZTEEG_X5 // (Azteeg X5 Boards) not tested yet!
@ -620,7 +620,7 @@
#define LIMIT_PORT LPC_GPIO1->FIOPIN
#define X_LIMIT_BIT 24 // X-MIN=24, X-MAX=27
#define Y_LIMIT_BIT 25 // Y-MIN=25, Y-MAX=28
#define Z_LIMIT_BIT 26 // Z-MIN=26, Z-MAX=29
#define Z_LIMIT_BIT 26 // Z-MIN=26, Z-MAX=29
#define A_LIMIT_BIT 27 // reuse p1.27, as X-MAX is not used
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)|(1<<A_LIMIT_BIT)) // All limit bits
@ -632,7 +632,7 @@
#define COOLANT_MIST_PORT LPC_GPIO2->FIOPIN
#define COOLANT_MIST_BIT 7 // BED MOSFET (P2.7)
#define ENABLE_M7 // enables COOLANT MIST
// Define user-control controls (cycle start, reset, feed hold) input pins.
// NOTE: All CONTROLs pins must be on the same port and not on a port with other input pins (limits).
#define CONTROL_DDR NotUsed
@ -658,8 +658,8 @@
// The LPC17xx has 6 PWM channels. Each channel has 2 pins. It can drive both pins simultaneously to the same value.
//
// PWM Channel PWM1_CH1 PWM1_CH2 PWM1_CH3 PWM1_CH4 PWM1_CH5 PWM1_CH6
// Primary pin P1.18 P1.20 P1.21 P1.23 P1.24 P1.26
// Secondary pin P2.0 P2.1 P2.2 P2.3 P2.4 P2.5
// Primary pin P1.18 P1.20 P1.21 P1.23 P1.24 P1.26
// Secondary pin P2.0 P2.1 P2.2 P2.3 P2.4 P2.5
#ifdef SPINDLE_PWM_PIN_2_4
#define SPINDLE_PWM_CHANNEL PWM1_CH5 // MOSFET3 (P2.4)
#else
@ -678,11 +678,11 @@
#endif
//#define SPINDLE_PWM_OFF_VALUE 0 // Defined in config.h
#define SPINDLE_PWM_RANGE (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_TCCRA_REGISTER TCCR2A
#define SPINDLE_TCCRB_REGISTER TCCR2B
#define SPINDLE_OCR_REGISTER OCR2A
#define SPINDLE_COMB_BIT COM2A1
#endif
#define SPINDLE_COMB_BIT COM2A1
#endif // end of CPU_MAP_AZTEEG_X5
/*

View File

@ -77,7 +77,7 @@
#define DEFAULT_SPINDLE_PWM_OFF_VALUE 0 // $34 % (% of PWM when spindle is off)
#define DEFAULT_SPINDLE_PWM_MIN_VALUE 1 // $35 % (% of PWM when spindle is at lowest setting)
#define DEFAULT_SPINDLE_PWM_MAX_VALUE 100 // $36 % (% of PWM when spindle is at highest setting)
// Up to 3 HOMING_CYCLE_x can be defined, specifying which axes are homed and in which order
// Up to 4 HOMING_CYCLE_x can be defined (0-3), specifying which axes are homed and in which order
#define HOMING_CYCLE_0 ((1<<X_AXIS)|(1<<Y_AXIS))
#endif // end of DEFAULTS_GENERIC

View File

@ -158,9 +158,9 @@ void limits_go_home(uint8_t cycle_mask)
// Initialize variables used for homing computations.
uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1);
uint32_t step_pin[N_AXIS];
uint32_t step_pin[N_AXIS]; // Tracks which pins correspond to which axes (reduces calls to get_step_pin_mask())
float target[N_AXIS];
float max_travel = 0.0;
float max_travel = 0.0; // Maximum travel distance to move searching for limits
uint8_t idx;
for (idx=0; idx<N_AXIS; idx++) {
// Initialize step pin masks
@ -183,11 +183,12 @@ void limits_go_home(uint8_t cycle_mask)
uint32_t limit_state, axislock, n_active_axis;
do {
// convert current sys_position (steps) to target (mm) so unused axes remain in place
system_convert_array_steps_to_mpos(target,sys_position);
// Initialize and declare variables needed for homing routine.
axislock = 0;
n_active_axis = 0;
axislock = 0; // Track which pins still need to find limits. Lock these axes by clearing these bits.
n_active_axis = 0; // Track number of axes being homed
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))) {
@ -215,7 +216,7 @@ void limits_go_home(uint8_t cycle_mask)
if (approach) { target[idx] = max_travel; }
else { target[idx] = -max_travel; }
}
// Apply axislock to the step port pins active in this cycle.
// Apply axislock to the step port pins active in this cycle, allowing motion
axislock |= step_pin[idx];
}
@ -235,15 +236,14 @@ void limits_go_home(uint8_t cycle_mask)
// 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)) {
#ifdef COREXY
if (idx==Z_AXIS) { axislock &= ~(step_pin[Z_AXIS]); }
else { axislock &= ~(step_pin[A_MOTOR]|step_pin[B_MOTOR]); }
#else
axislock &= ~(step_pin[idx]);
#endif
}
if ((axislock & step_pin[idx]) && (limit_state & (1 << idx))) {
// Clear the axislock bits to prevent axis from moving after limit is hit
#ifdef COREXY
if (idx==Z_AXIS) { axislock &= ~(step_pin[Z_AXIS]); }
else { axislock &= ~(step_pin[A_MOTOR]|step_pin[B_MOTOR]); }
#else
axislock &= ~(step_pin[idx]);
#endif
}
}
sys.homing_axis_lock = axislock;
@ -297,7 +297,7 @@ void limits_go_home(uint8_t cycle_mask)
// 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.
// triggering when hard limits are enabled or when more than one axis shares a limit pin.
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++) {

View File

@ -42,13 +42,13 @@ int main(void)
{
// Initialize system upon power-up.
debug_init(); // Initialize debug leds
isr_init(); // Set ISR priorities
delay_init(); // Setup delay timer
isr_init(); // Set ISR priorities (stepper ISR uses Timer1)
delay_init(); // Setup delay timer (uses Timer3)
serial_init(); // Setup serial baud rate and interrupts
eeprom_init(); // Init EEPROM or FLASH
eeprom_init(); // Init EEPROM or Flash
settings_init(); // Load Grbl settings from EEPROM
current_init(); // Configure stepper driver current
stepper_init(); // Configure stepper pins and interrupt timers
stepper_init(); // Configure stepper pins and interrupt timers (uses Timer1)
system_init(); // Configure pinout pins and pin-change interrupt
memset(sys_position,0,sizeof(sys_position)); // Clear machine position.
@ -61,7 +61,7 @@ int main(void)
#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
@ -84,26 +84,26 @@ int main(void)
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;
memset(sys_probe_position,0,sizeof(sys_probe_position)); // Clear probe position.
sys_probe_state = 0; // PROBE_OFF
sys_rt_exec_state = 0; // EXEC_STATUS_REPORT
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.
gc_init(); // Set g-code parser to default state
spindle_init(); // Configure spindle pins and PWM values
coolant_init(); // Configure coolant pins
limits_init(); // Configure limit input pins and interrupts
probe_init(); // Configure probe input pin
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();
plan_sync_position(); // Synchronize plan position with (actual) system position
gc_sync_position(); // Synchronize g-code position with (actual) system position
// Print welcome message. Indicates an initialization has occured at power-up or with a reset.
report_init_message();

View File

@ -100,14 +100,14 @@ void settings_restore(uint8_t restore_flag) {
settings.homing_pulloff = DEFAULT_HOMING_PULLOFF;
settings.flags = 0;
if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; }
if (DEFAULT_LASER_MODE) { settings.flags |= BITFLAG_LASER_MODE; }
if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; }
if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; }
if (DEFAULT_LASER_MODE) { settings.flags |= BITFLAG_LASER_MODE; }
if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; }
if (DEFAULT_HARD_LIMIT_ENABLE) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; }
if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; }
if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; }
if (DEFAULT_SOFT_LIMIT_ENABLE) { settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; }
if (DEFAULT_INVERT_LIMIT_PINS) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; }
if (DEFAULT_INVERT_PROBE_PIN) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; }
if (DEFAULT_INVERT_PROBE_PIN) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; }
settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM;
settings.steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM;
@ -177,7 +177,7 @@ uint8_t settings_read_startup_line(uint8_t n, char *line)
if (!(memcpy_from_eeprom_with_checksum((char*)line, addr, LINE_BUFFER_SIZE))) {
// Reset line with default value
line[0] = 0; // Empty line
settings_store_startup_line(n, line);
settings_store_startup_line(n, line); // Clear this startup line because it's corrupted
return(false);
}
return(true);
@ -190,7 +190,7 @@ uint8_t settings_read_build_info(char *line)
if (!(memcpy_from_eeprom_with_checksum((char*)line, EEPROM_ADDR_BUILD_INFO, LINE_BUFFER_SIZE))) {
// Reset line with default value
line[0] = 0; // Empty line
settings_store_build_info(line);
settings_store_build_info(line); // Clear out build info string because it's corrupted
return(false);
}
return(true);

View File

@ -26,7 +26,7 @@
// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
// when firmware is upgraded. Always stored in byte 0 of eeprom
// when firmware is upgraded. Always stored in byte 0 of EEPROM.
#define SETTINGS_VERSION 11 // NOTE: Check settings_reset() when moving to next version.
// Define bit flag masks for the boolean settings in settings.flag.
@ -44,10 +44,10 @@
#define BITFLAG_RT_STATUS_BUFFER_STATE bit(1)
// Define settings restore bitflags.
#define SETTINGS_RESTORE_DEFAULTS bit(0)
#define SETTINGS_RESTORE_PARAMETERS bit(1)
#define SETTINGS_RESTORE_DEFAULTS bit(0)
#define SETTINGS_RESTORE_PARAMETERS bit(1)
#define SETTINGS_RESTORE_STARTUP_LINES bit(2)
#define SETTINGS_RESTORE_BUILD_INFO bit(3)
#define SETTINGS_RESTORE_BUILD_INFO bit(3)
#ifndef SETTINGS_RESTORE_ALL
#define SETTINGS_RESTORE_ALL 0xFF // All bitflags
#endif
@ -56,6 +56,7 @@
// NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and
// the startup script. The lower half contains the global settings and space for future
// developments.
// Note: Address 0 of EEPROM is reserved for SETTINGS_VERSION.
#define EEPROM_ADDR_GLOBAL 1U
#define EEPROM_ADDR_PARAMETERS 512U
#define EEPROM_ADDR_STARTUP_BLOCK 768U
@ -80,7 +81,7 @@ typedef struct {
float steps_per_mm[N_AXIS];
float max_rate[N_AXIS];
float acceleration[N_AXIS];
float max_travel[N_AXIS];
float max_travel[N_AXIS]; // NOTE: Stored as a negative value
float current[N_AXIS];
// Remaining Grbl settings

View File

@ -30,10 +30,10 @@
#define RAMP_DECEL 2
#define RAMP_DECEL_OVERRIDE 3
#define PREP_FLAG_RECALCULATE bit(0)
#define PREP_FLAG_RECALCULATE bit(0)
#define PREP_FLAG_HOLD_PARTIAL_BLOCK bit(1)
#define PREP_FLAG_PARKING bit(2)
#define PREP_FLAG_DECEL_OVERRIDE bit(3)
#define PREP_FLAG_PARKING bit(2)
#define PREP_FLAG_DECEL_OVERRIDE bit(3)
// Define Adaptive Multi-Axis Step-Smoothing(AMASS) levels and cutoff frequencies. The highest level
// frequency bin starts at 0Hz and ends at its cutoff frequency. The next lower level frequency bin
@ -45,11 +45,11 @@
// NOTE: Current settings are set to overdrive the ISR to no more than 16kHz, balancing CPU overhead
// and timer accuracy. Do not alter these settings unless you know what you are doing.
#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
#define MAX_AMASS_LEVEL 3
// AMASS_LEVEL0: Normal operation. No AMASS. No upper cutoff frequency. Starts at LEVEL1 cutoff frequency.
#define AMASS_LEVEL1 (F_CPU/8000) // Over-drives ISR (x2). Defined as F_CPU/(Cutoff frequency in Hz)
#define AMASS_LEVEL2 (F_CPU/4000) // Over-drives ISR (x4)
#define AMASS_LEVEL3 (F_CPU/2000) // Over-drives ISR (x8)
#define MAX_AMASS_LEVEL 3
// AMASS_LEVEL0: Normal operation. No AMASS. No upper cutoff frequency. Starts at LEVEL1 cutoff frequency.
#define AMASS_LEVEL1 (F_CPU/8000) // Over-drives ISR (x2). Defined as F_CPU/(Cutoff frequency in Hz)
#define AMASS_LEVEL2 (F_CPU/4000) // Over-drives ISR (x4)
#define AMASS_LEVEL3 (F_CPU/2000) // Over-drives ISR (x8)
#if MAX_AMASS_LEVEL <= 0
error "AMASS must have 1 or more levels to operate correctly."
@ -167,7 +167,7 @@ typedef struct {
#ifdef VARIABLE_SPINDLE
float inv_rate; // Used by PWM laser mode to speed up segment calculations.
uint32_t current_spindle_pwm;
uint32_t current_spindle_pwm;
#endif
} st_prep_t;
static st_prep_t prep;
@ -235,9 +235,9 @@ void st_wake_up()
#endif
// Enable Stepper Driver Interrupt Timer
LPC_TIM1->TCR = 0b10; // reset
LPC_TIM1->MR0 = 4000; // Generate first interrupt soon
LPC_TIM1->TCR = 0b01; // enable
LPC_TIM1->TCR = 0b10; // reset Timer Control (0b10=Reset, 0b01=Enable)
LPC_TIM1->MR0 = 4000; // Generate first interrupt soon (Match Register for TC)
LPC_TIM1->TCR = 0b01; // enable Timer Control (0b10=Reset, 0b01=Enable)
}
@ -245,19 +245,19 @@ void st_wake_up()
void st_go_idle()
{
// Disable Stepper Driver Interrupt. Allow Stepper Port Reset Interrupt to finish, if active.
LPC_TIM1->TCR = 0; // Disable Timer1
LPC_TIM1->TCR = 0; // Disable Timer1 Control (0b10=Reset, 0b01=Enable)
busy = false;
// Set stepper driver idle state, disabled or enabled, depending on settings and circumstances.
bool pin_state = false; // Keep enabled.
bool disableStepper = false; // Keep enabled by default.
if (((settings.stepper_idle_lock_time != 0xff) || sys_rt_exec_alarm || sys.state == STATE_SLEEP) && sys.state != STATE_HOMING) {
// Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete
// stop and not drift from residual inertial forces at the end of the last movement.
delay_ms(settings.stepper_idle_lock_time);
pin_state = true; // Override. Disable steppers.
disableStepper = true; // Override. Disable steppers.
}
if (bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)) { pin_state = !pin_state; } // Apply pin invert.
if (pin_state) { STEPPERS_DISABLE_PORT |= STEPPERS_DISABLE_MASK; }
if (bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)) { disableStepper = !disableStepper; } // Apply pin invert.
if (disableStepper) { STEPPERS_DISABLE_PORT |= STEPPERS_DISABLE_MASK; }
else { STEPPERS_DISABLE_PORT &= ~STEPPERS_DISABLE_MASK; }
}
@ -355,7 +355,7 @@ extern "C" void TIMER1_IRQHandler()
#endif
// Initialize step segment timing per step and load number of steps to execute.
LPC_TIM1->MR0 = st.exec_segment->cycles_per_tick;
LPC_TIM1->MR0 = st.exec_segment->cycles_per_tick; // Set Match Register to wait one tick
st.step_count = st.exec_segment->n_step; // NOTE: Can sometimes be zero when moving slow.
// If the new segment starts a new planner block, initialize stepper variables and counters.
// NOTE: When the segment data index changes, this indicates a new planner block.
@ -503,7 +503,7 @@ extern "C" void TIMER1_IRQHandler()
cause issues at high step rates if another high frequency asynchronous interrupt is
added to Grbl.
*/
/* Not ported; the main ISR assumes short pulse widths and handles it. Stepper drivers with
/* Not ported; the main ISR assumes short pulse widths and handles it. Stepper drivers with
long pulse widths may need this instead if they cause the main ISR to consume too much time.
// This interrupt is enabled by ISR_TIMER1_COMPAREA when it sets the motor port bits to execute
// a step. This ISR resets the motor port after a short period (settings.pulse_microseconds)
@ -570,17 +570,17 @@ void st_reset()
void stepper_init()
{
// Configure step and direction interface pins
STEP_DDR |= STEP_MASK;
STEPPERS_DISABLE_DDR |= STEPPERS_DISABLE_MASK;
DIRECTION_DDR |= DIRECTION_MASK;
STEP_DDR |= STEP_MASK; // Set selected stepper step pins as outputs
STEPPERS_DISABLE_DDR |= STEPPERS_DISABLE_MASK; // Set selected stepper disable pins as outputs
DIRECTION_DDR |= DIRECTION_MASK; // Set selected stepper direction pins as outputs
// Configure Timer 1: Stepper Driver Interrupt
LPC_TIM1->TCR = 0; // disable
LPC_TIM1->CTCR = 0; // timer mode
LPC_TIM1->PR = 0; // no prescale
LPC_TIM1->MCR = 0b011; // MR0: !stop, reset, interrupt
LPC_TIM1->CCR = 0; // no capture
LPC_TIM1->EMR = 0; // no external match
LPC_TIM1->TCR = 0; // disable Timer Control (0b10=Reset, 0b01=Enable)
LPC_TIM1->CTCR = 0; // Count Control (0=TimerMode, 1-3=EdgeCounterMode)
LPC_TIM1->PR = 0; // no Prescale (TC increments every PR+1 clocks)
LPC_TIM1->MCR = 0b011; // Match Control (0b001=InterruptEnbl, 0b010=Reset_Enbl, 0b100=Stop_Enbl)
LPC_TIM1->CCR = 0; // no Capture Control actions
LPC_TIM1->EMR = 0; // no External Match (controls external match pins)
NVIC_EnableIRQ(TIMER1_IRQn); // Enable Stepper Driver Interrupt
}
@ -717,49 +717,49 @@ void st_prep_buffer()
} else {
prep.current_speed = sqrt(pl_block->entry_speed_sqr);
}
#ifdef VARIABLE_SPINDLE
// Setup laser mode variables. PWM rate adjusted motions will always complete a motion with the
// spindle off.
// spindle off.
st_prep_block->is_pwm_rate_adjusted = false;
if (settings.flags & BITFLAG_LASER_MODE) {
if (pl_block->condition & PL_COND_FLAG_SPINDLE_CCW) {
if (pl_block->condition & PL_COND_FLAG_SPINDLE_CCW) {
// Pre-compute inverse programmed rate to speed up PWM updating per step segment.
prep.inv_rate = 1.0/pl_block->programmed_rate;
st_prep_block->is_pwm_rate_adjusted = true;
st_prep_block->is_pwm_rate_adjusted = true;
}
}
#endif
}
/* ---------------------------------------------------------------------------------
Compute the velocity profile of a new planner block based on its entry and exit
speeds, or recompute the profile of a partially-completed planner block if the
planner has updated it. For a commanded forced-deceleration, such as from a feed
hold, override the planner velocities and decelerate to the target exit speed.
*/
prep.mm_complete = 0.0; // Default velocity profile complete at 0.0mm from end of block.
float inv_2_accel = 0.5/pl_block->acceleration;
if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { // [Forced Deceleration to Zero Velocity]
// Compute velocity profile parameters for a feed hold in-progress. This profile overrides
// the planner block profile, enforcing a deceleration to zero speed.
prep.ramp_type = RAMP_DECEL;
// Compute decelerate distance relative to end of block.
float decel_dist = pl_block->millimeters - inv_2_accel*pl_block->entry_speed_sqr;
if (decel_dist < 0.0) {
// Deceleration through entire planner block. End of feed hold is not in this block.
prep.exit_speed = sqrt(pl_block->entry_speed_sqr-2*pl_block->acceleration*pl_block->millimeters);
} else {
prep.mm_complete = decel_dist; // End of feed hold.
prep.exit_speed = 0.0;
}
} else { // [Normal Operation]
// Compute or recompute velocity profile parameters of the prepped planner block.
prep.ramp_type = RAMP_ACCEL; // Initialize as acceleration ramp.
prep.accelerate_until = pl_block->millimeters;
/* ---------------------------------------------------------------------------------
Compute the velocity profile of a new planner block based on its entry and exit
speeds, or recompute the profile of a partially-completed planner block if the
planner has updated it. For a commanded forced-deceleration, such as from a feed
hold, override the planner velocities and decelerate to the target exit speed.
*/
prep.mm_complete = 0.0; // Default velocity profile complete at 0.0mm from end of block.
float inv_2_accel = 0.5/pl_block->acceleration;
if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { // [Forced Deceleration to Zero Velocity]
// Compute velocity profile parameters for a feed hold in-progress. This profile overrides
// the planner block profile, enforcing a deceleration to zero speed.
prep.ramp_type = RAMP_DECEL;
// Compute decelerate distance relative to end of block.
float decel_dist = pl_block->millimeters - inv_2_accel*pl_block->entry_speed_sqr;
if (decel_dist < 0.0) {
// Deceleration through entire planner block. End of feed hold is not in this block.
prep.exit_speed = sqrt(pl_block->entry_speed_sqr-2*pl_block->acceleration*pl_block->millimeters);
} else {
prep.mm_complete = decel_dist; // End of feed hold.
prep.exit_speed = 0.0;
}
} else { // [Normal Operation]
// Compute or recompute velocity profile parameters of the prepped planner block.
prep.ramp_type = RAMP_ACCEL; // Initialize as acceleration ramp.
prep.accelerate_until = pl_block->millimeters;
float exit_speed_sqr;
float nominal_speed;
float exit_speed_sqr;
float nominal_speed;
if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) {
prep.exit_speed = exit_speed_sqr = 0.0; // Enforce stop at end of system motion.
} else {
@ -768,9 +768,9 @@ void st_prep_buffer()
}
nominal_speed = plan_compute_profile_nominal_speed(pl_block);
float nominal_speed_sqr = nominal_speed*nominal_speed;
float intersect_distance =
0.5*(pl_block->millimeters+inv_2_accel*(pl_block->entry_speed_sqr-exit_speed_sqr));
float nominal_speed_sqr = nominal_speed*nominal_speed;
float intersect_distance =
0.5*(pl_block->millimeters+inv_2_accel*(pl_block->entry_speed_sqr-exit_speed_sqr));
if (pl_block->entry_speed_sqr > nominal_speed_sqr) { // Only occurs during override reductions.
prep.accelerate_until = pl_block->millimeters - inv_2_accel*(pl_block->entry_speed_sqr-nominal_speed_sqr);
@ -793,41 +793,41 @@ void st_prep_buffer()
prep.maximum_speed = nominal_speed;
prep.ramp_type = RAMP_DECEL_OVERRIDE;
}
} else if (intersect_distance > 0.0) {
if (intersect_distance < pl_block->millimeters) { // Either trapezoid or triangle types
// NOTE: For acceleration-cruise and cruise-only types, following calculation will be 0.0.
prep.decelerate_after = inv_2_accel*(nominal_speed_sqr-exit_speed_sqr);
if (prep.decelerate_after < intersect_distance) { // Trapezoid type
prep.maximum_speed = nominal_speed;
if (pl_block->entry_speed_sqr == nominal_speed_sqr) {
// Cruise-deceleration or cruise-only type.
prep.ramp_type = RAMP_CRUISE;
} else {
// Full-trapezoid or acceleration-cruise types
prep.accelerate_until -= inv_2_accel*(nominal_speed_sqr-pl_block->entry_speed_sqr);
}
} else { // Triangle type
prep.accelerate_until = intersect_distance;
prep.decelerate_after = intersect_distance;
prep.maximum_speed = sqrt(2.0*pl_block->acceleration*intersect_distance+exit_speed_sqr);
}
} else { // Deceleration-only type
} else if (intersect_distance > 0.0) {
if (intersect_distance < pl_block->millimeters) { // Either trapezoid or triangle types
// NOTE: For acceleration-cruise and cruise-only types, following calculation will be 0.0.
prep.decelerate_after = inv_2_accel*(nominal_speed_sqr-exit_speed_sqr);
if (prep.decelerate_after < intersect_distance) { // Trapezoid type
prep.maximum_speed = nominal_speed;
if (pl_block->entry_speed_sqr == nominal_speed_sqr) {
// Cruise-deceleration or cruise-only type.
prep.ramp_type = RAMP_CRUISE;
} else {
// Full-trapezoid or acceleration-cruise types
prep.accelerate_until -= inv_2_accel*(nominal_speed_sqr-pl_block->entry_speed_sqr);
}
} else { // Triangle type
prep.accelerate_until = intersect_distance;
prep.decelerate_after = intersect_distance;
prep.maximum_speed = sqrt(2.0*pl_block->acceleration*intersect_distance+exit_speed_sqr);
}
} else { // Deceleration-only type
prep.ramp_type = RAMP_DECEL;
// prep.decelerate_after = pl_block->millimeters;
// prep.maximum_speed = prep.current_speed;
}
} else { // Acceleration-only type
prep.accelerate_until = 0.0;
// prep.decelerate_after = 0.0;
prep.maximum_speed = prep.exit_speed;
}
}
}
} else { // Acceleration-only type
prep.accelerate_until = 0.0;
// prep.decelerate_after = 0.0;
prep.maximum_speed = prep.exit_speed;
}
}
#ifdef VARIABLE_SPINDLE
bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); // Force update whenever updating block.
#endif
}
// Initialize new segment
segment_t *prep_segment = &segment_buffer[segment_buffer_head];
@ -937,16 +937,16 @@ void st_prep_buffer()
/* -----------------------------------------------------------------------------------
Compute spindle speed PWM output for step segment
*/
if (st_prep_block->is_pwm_rate_adjusted || (sys.step_control & STEP_CONTROL_UPDATE_SPINDLE_PWM)) {
if (pl_block->condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)) {
float rpm = pl_block->spindle_speed;
// NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate.
// NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate.
if (st_prep_block->is_pwm_rate_adjusted) { rpm *= (prep.current_speed * prep.inv_rate); }
// If current_speed is zero, then may need to be rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE)
// but this would be instantaneous only and during a motion. May not matter at all.
prep.current_spindle_pwm = spindle_compute_pwm_value(rpm);
} else {
} else {
sys.spindle_speed = 0.0;
prep.current_spindle_pwm = spindle_pwm_off_value;
}
@ -955,7 +955,7 @@ void st_prep_buffer()
prep_segment->spindle_pwm = prep.current_spindle_pwm; // Reload segment PWM value
#endif
/* -----------------------------------------------------------------------------------
Compute segment step rate, steps to execute, and apply necessary rate corrections.
NOTE: Steps are computed by direct scalar conversion of the millimeter distance

View File

@ -23,14 +23,15 @@
void system_init()
{
// Configure user control pins (for cycle start, reset, feed hold, etc.)
CONTROL_DDR &= ~(CONTROL_MASK); // Configure as input pins
#ifdef DISABLE_CONTROL_PIN_PULL_UP
CONTROL_PORT &= ~(CONTROL_MASK); // Normal low operation. Requires external pull-down.
#else
CONTROL_PORT |= CONTROL_MASK; // Enable internal pull-up resistors. Normal high operation.
CONTROL_PORT |= CONTROL_MASK; // Enable internal pull-up resistors. Normal high operation.
#endif
CONTROL_PCMSK |= CONTROL_MASK; // Enable specific pins of the Pin Change Interrupt
PCICR |= (1 << CONTROL_INT); // Enable Pin Change Interrupt
CONTROL_PCMSK |= CONTROL_MASK; // Enable specific pins of the Pin Change Interrupt
PCICR |= (1 << CONTROL_INT); // Enable Pin Change Interrupt
}
@ -195,7 +196,7 @@ uint8_t system_execute_line(char *line)
if (!sys.abort) { // Execute startup scripts after successful homing.
sys.state = STATE_IDLE; // Set to IDLE when complete.
st_go_idle(); // Set steppers to the settings idle state before returning.
if (line[2] == 0) { system_execute_startup(line); }
if (line[2] == 0) { system_execute_startup(line); } // Execute startup script again.
}
break;
case 'S' : // Puts Grbl to sleep [IDLE/ALARM]