// Perform homing cycle to locate and set machine zero. Only '$H' executes this command. // NOTE: There should be no motions in the buffer and Grbl must be in an idle state before // executing the homing cycle. This prevents incorrect buffered plans after homing. void MotionGoHome(void) { plan_init(); uint16_t limitStatus; uint16_t stepCount; sys.state = STATE_HOMING; // Set system state variable // LIMIT_PCMSK &= ~LIMIT_MASK; // Disable hard limits pin change register for cycle duration xLimitDetected = FALSE; yLimitDetected = FALSE; BSP_SetStepSize(X_AXIS, QUARTER); BSP_SetStepSize(Y_AXIS, QUARTER); BSP_SetStepSize(Z_AXIS, QUARTER); settings.steps_per_mm[X_AXIS] = X_STEPS_MM(QUARTER_STEP); settings.steps_per_mm[Y_AXIS] = Y_STEPS_MM(QUARTER_STEP); settings.steps_per_mm[Z_AXIS] = Z_STEPS_MM(QUARTER_STEP); // Find out if X or Y axis are at limit limitStatus = mPORTCReadBits(xLimitInput.pin||yLimitInput.pin); if(limitStatus) { if(limitStatus & xLimitInput.pin) // If Xat Limit { stepCount = 0; BSP_Timer3Start(100); OpenOC2(XS_PWM_ENA, (ReadPeriod3()>>1), ReadPeriod3()>>1); BSP_AxisEnable(X_AXIS, NEGATIVE); while((mPORTCReadBits(xLimitInput.pin))) { stepCount++; steps_X = 0x1; if(stepCount >= 20) mPORTGToggleBits(xAxis.directionPin.pin); } BSP_AxisDisable(X_AXIS); if(mPORTGReadBits(xAxis.directionPin.pin) == POSITIVE) gcode.position[X_AXIS] = 215.000; else gcode.position[X_AXIS] =0; } if(limitStatus & yLimitInput.pin) // If Xat Limit { stepCount = 0; BSP_Timer2Start(100); OpenOC1(XS_PWM_ENA, (ReadPeriod2()>>1), ReadPeriod2()>>1); BSP_AxisEnable(Y_AXIS, NEGATIVE); while((mPORTCReadBits(yLimitInput.pin))) { stepCount++; steps_Y = 0x1; if(stepCount >= 20) mPORTEToggleBits(yAxis.directionPin.pin); } if(mPORTEReadBits(xAxis.directionPin.pin) == POSITIVE) gcode.position[Y_AXIS] = 215.000; else gcode.position[Y_AXIS] =0; }
/* * Helper function for getting timer periods. * The timer period is the maximum value for a output compare register. * Setting the OCRn register to the timer period results in the fastest * motor speed. */ static uint32_t get_timer_period(struct hbridge_info* hbridge) { uint32_t retval = 0; switch(hbridge->tmrn) { case 1: retval = ReadPeriod1(); break; case 2: retval = ReadPeriod2(); break; case 3: retval = ReadPeriod3(); break; case 4: retval = ReadPeriod4(); break; case 5: retval = ReadPeriod5(); break; } }
//Main Timer for total movement time and block handling void __ISR(_TIMER_1_VECTOR, ipl3) _InterruptHandler_TMR1(void) { // clear the interrupt flag mT1ClearIntFlag(); if(current_block == Null) { current_block = plan_get_current_block(); if(current_block != Null) { if(current_block->activeAxisCount == 3) { if(current_block->minStepAxis < N_AXIS) // If they are not all equal // TODO: If any of the step counts are equal we dont need Timer4 { switch(current_block->minStepAxis) // Need to configure OC Module to be Single Pulse Output and other two OC modules to be continuous pulse { case X_AXIS: BSP_Timer4Start((uint16_t)current_block->steppingFreq[X_AXIS]);// Use Timer4 Interrupt to trigger single output pulse OpenOC2((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER3_SRC|OC_SINGLE_PULSE), (ReadPeriod3()>>1), ReadPeriod3()); // X_AXIS = Single Pulse BSP_Timer2Start((uint16_t)current_block->steppingFreq[Y_AXIS]); OpenOC1((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER2_SRC|OC_CONTINUE_PULSE), (ReadPeriod2()>>1), ReadPeriod2()); // Y_AXIS = Continuous Pulse BSP_Timer3Start((uint16_t)current_block->steppingFreq[Z_AXIS]); OpenOC3((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER3_SRC|OC_CONTINUE_PULSE), (ReadPeriod3()>>1), ReadPeriod3()); // Z_AXIS = Continuous Pulse break; case Y_AXIS: BSP_Timer4Start((uint16_t)current_block->steppingFreq[Y_AXIS]);// Use Timer4 Interrupt to trigger single output pulse OpenOC1((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER3_SRC|OC_SINGLE_PULSE), (ReadPeriod3()>>1), ReadPeriod3()); // Y_AXIS = Single Pulse BSP_Timer2Start((uint16_t)current_block->steppingFreq[X_AXIS]); OpenOC2((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER2_SRC|OC_CONTINUE_PULSE), (ReadPeriod2()>>1), ReadPeriod2()); // X_AXIS = Continuous Pulse BSP_Timer3Start((uint16_t)current_block->steppingFreq[Z_AXIS]); OpenOC3((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER3_SRC|OC_CONTINUE_PULSE), (ReadPeriod3()>>1), ReadPeriod3()); // Z_AXIS = Continuous Pulse break; case Z_AXIS: BSP_Timer4Start((uint16_t)current_block->steppingFreq[Z_AXIS]);// Use Timer4 Interrupt to trigger single output pulse OpenOC3((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER3_SRC|OC_SINGLE_PULSE), (ReadPeriod3()>>1), ReadPeriod3()); // Z_AXIS = Single Pulse BSP_Timer3Start((uint16_t)current_block->steppingFreq[X_AXIS]); OpenOC2((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER3_SRC|OC_CONTINUE_PULSE), (ReadPeriod3()>>1), ReadPeriod3()); // X_AXIS = Continuous Pulse BSP_Timer2Start((uint16_t)current_block->steppingFreq[Y_AXIS]); OpenOC1((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER2_SRC|OC_CONTINUE_PULSE), (ReadPeriod2()>>1), ReadPeriod2()); // Y_AXIS = Continuous Pulse break; default: // error break; } } else { BSP_Timer2Start((uint16_t)current_block->steppingFreq[X_AXIS]); // All Steps Counts are equal so just use on timer OpenOC1((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER2_SRC|OC_CONTINUE_PULSE), (ReadPeriod2()>>1), ReadPeriod2()); // Y_AXIS = Continuous Pulse OpenOC2((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER2_SRC|OC_CONTINUE_PULSE), (ReadPeriod2()>>1), ReadPeriod2()); // X_AXIS = Continuous Pulse OpenOC3((OC_ON|OC_IDLE_STOP|OC_TIMER_MODE16 \ |OC_TIMER2_SRC|OC_CONTINUE_PULSE), (ReadPeriod2()>>1), ReadPeriod2()); // Z_AXIS = Continuous Pulse } BSP_AxisEnable(Y_AXIS, current_block->direction_bits[Y_AXIS]); BSP_AxisEnable(X_AXIS, current_block->direction_bits[X_AXIS]); BSP_AxisEnable(Z_AXIS, current_block->direction_bits[Z_AXIS]); } else if (current_block->activeAxisCount == 2) // 2 Axis Enabled